1e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu/** 2e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu * Copyright (c) 2016, The Android Open Source Project 3e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu * 4e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu * Licensed under the Apache License, Version 2.0 (the "License"); 5e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu * you may not use this file except in compliance with the License. 6e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu * You may obtain a copy of the License at 7e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu * 8e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu * http://www.apache.org/licenses/LICENSE-2.0 9e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu * 10e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu * Unless required by applicable law or agreed to in writing, software 11e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu * distributed under the License is distributed on an "AS IS" BASIS, 12e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu * See the License for the specific language governing permissions and 14e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu * limitations under the License. 15e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu */ 16e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu 17e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiupackage android.net.wifi.hotspot2.pps; 18e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu 19a25d717de870895be52e81b585a8484fff0c6109Peter Qiuimport android.net.wifi.EAPConstants; 20e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiuimport android.net.wifi.ParcelUtil; 21e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiuimport android.os.Parcelable; 22e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiuimport android.os.Parcel; 23e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiuimport android.text.TextUtils; 24a25d717de870895be52e81b585a8484fff0c6109Peter Qiuimport android.util.Log; 25e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu 26444dc5d099788e5aa0fd0e664fd952fbb07a69d4Peter Qiuimport java.nio.charset.StandardCharsets; 27a25d717de870895be52e81b585a8484fff0c6109Peter Qiuimport java.security.MessageDigest; 28a25d717de870895be52e81b585a8484fff0c6109Peter Qiuimport java.security.NoSuchAlgorithmException; 29e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiuimport java.security.PrivateKey; 30e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiuimport java.security.cert.CertificateEncodingException; 31e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiuimport java.security.cert.X509Certificate; 32e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiuimport java.util.Arrays; 3389537734e19fac6947ee14a1b912c5c135042837Peter Qiuimport java.util.Date; 34a25d717de870895be52e81b585a8484fff0c6109Peter Qiuimport java.util.HashSet; 35ddafc73496e3bab135ac7249bfb3cf4d871e5cf2Peter Qiuimport java.util.Objects; 36a25d717de870895be52e81b585a8484fff0c6109Peter Qiuimport java.util.Set; 37e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu 38e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu/** 39e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu * Class representing Credential subtree in the PerProviderSubscription (PPS) 40e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu * Management Object (MO) tree. 41e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu * For more info, refer to Hotspot 2.0 PPS MO defined in section 9.1 of the Hotspot 2.0 42e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu * Release 2 Technical Specification. 43e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu * 44e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu * In addition to the fields in the Credential subtree, this will also maintain necessary 45e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu * information for the private key and certificates associated with this credential. 46e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu */ 47e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiupublic final class Credential implements Parcelable { 48a25d717de870895be52e81b585a8484fff0c6109Peter Qiu private static final String TAG = "Credential"; 49a25d717de870895be52e81b585a8484fff0c6109Peter Qiu 50a25d717de870895be52e81b585a8484fff0c6109Peter Qiu /** 51a25d717de870895be52e81b585a8484fff0c6109Peter Qiu * Max string length for realm. Refer to Credential/Realm node in Hotspot 2.0 Release 2 52a25d717de870895be52e81b585a8484fff0c6109Peter Qiu * Technical Specification Section 9.1 for more info. 53a25d717de870895be52e81b585a8484fff0c6109Peter Qiu */ 54444dc5d099788e5aa0fd0e664fd952fbb07a69d4Peter Qiu private static final int MAX_REALM_BYTES = 253; 55444dc5d099788e5aa0fd0e664fd952fbb07a69d4Peter Qiu 56444dc5d099788e5aa0fd0e664fd952fbb07a69d4Peter Qiu /** 57444dc5d099788e5aa0fd0e664fd952fbb07a69d4Peter Qiu * The time this credential is created. It is in the format of number 58444dc5d099788e5aa0fd0e664fd952fbb07a69d4Peter Qiu * of milliseconds since January 1, 1970, 00:00:00 GMT. 59444dc5d099788e5aa0fd0e664fd952fbb07a69d4Peter Qiu * Using Long.MIN_VALUE to indicate unset value. 60444dc5d099788e5aa0fd0e664fd952fbb07a69d4Peter Qiu */ 61967501ec982f14fec6a160c03e34cd2d296d7128Peter Qiu private long mCreationTimeInMillis = Long.MIN_VALUE; 62a9f9889218ac972706830440990a59cbee685976Peter Qiu /** 63a9f9889218ac972706830440990a59cbee685976Peter Qiu * @hide 64a9f9889218ac972706830440990a59cbee685976Peter Qiu */ 65967501ec982f14fec6a160c03e34cd2d296d7128Peter Qiu public void setCreationTimeInMillis(long creationTimeInMillis) { 66967501ec982f14fec6a160c03e34cd2d296d7128Peter Qiu mCreationTimeInMillis = creationTimeInMillis; 67aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu } 68a9f9889218ac972706830440990a59cbee685976Peter Qiu /** 69a9f9889218ac972706830440990a59cbee685976Peter Qiu * @hide 70a9f9889218ac972706830440990a59cbee685976Peter Qiu */ 71967501ec982f14fec6a160c03e34cd2d296d7128Peter Qiu public long getCreationTimeInMillis() { 72967501ec982f14fec6a160c03e34cd2d296d7128Peter Qiu return mCreationTimeInMillis; 73aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu } 74444dc5d099788e5aa0fd0e664fd952fbb07a69d4Peter Qiu 75444dc5d099788e5aa0fd0e664fd952fbb07a69d4Peter Qiu /** 76444dc5d099788e5aa0fd0e664fd952fbb07a69d4Peter Qiu * The time this credential will expire. It is in the format of number 77444dc5d099788e5aa0fd0e664fd952fbb07a69d4Peter Qiu * of milliseconds since January 1, 1970, 00:00:00 GMT. 78444dc5d099788e5aa0fd0e664fd952fbb07a69d4Peter Qiu * Using Long.MIN_VALUE to indicate unset value. 79444dc5d099788e5aa0fd0e664fd952fbb07a69d4Peter Qiu */ 80967501ec982f14fec6a160c03e34cd2d296d7128Peter Qiu private long mExpirationTimeInMillis = Long.MIN_VALUE; 81a9f9889218ac972706830440990a59cbee685976Peter Qiu /** 82a9f9889218ac972706830440990a59cbee685976Peter Qiu * @hide 83a9f9889218ac972706830440990a59cbee685976Peter Qiu */ 84967501ec982f14fec6a160c03e34cd2d296d7128Peter Qiu public void setExpirationTimeInMillis(long expirationTimeInMillis) { 85967501ec982f14fec6a160c03e34cd2d296d7128Peter Qiu mExpirationTimeInMillis = expirationTimeInMillis; 86aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu } 87a9f9889218ac972706830440990a59cbee685976Peter Qiu /** 88a9f9889218ac972706830440990a59cbee685976Peter Qiu * @hide 89a9f9889218ac972706830440990a59cbee685976Peter Qiu */ 90967501ec982f14fec6a160c03e34cd2d296d7128Peter Qiu public long getExpirationTimeInMillis() { 91967501ec982f14fec6a160c03e34cd2d296d7128Peter Qiu return mExpirationTimeInMillis; 92aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu } 93a25d717de870895be52e81b585a8484fff0c6109Peter Qiu 94e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu /** 95e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu * The realm associated with this credential. It will be used to determine 96e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu * if this credential can be used to authenticate with a given hotspot by 97e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu * comparing the realm specified in that hotspot's ANQP element. 98e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu */ 99aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu private String mRealm = null; 100e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu /** 101e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * Set the realm associated with this credential. 102e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * 103e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * @param realm The realm to set to 104e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu */ 105aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu public void setRealm(String realm) { 106aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu mRealm = realm; 107aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu } 108e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu /** 109e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * Get the realm associated with this credential. 110e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * 111e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * @return the realm associated with this credential 112e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu */ 113aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu public String getRealm() { 114aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu return mRealm; 115aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu } 116e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu 117e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu /** 118444dc5d099788e5aa0fd0e664fd952fbb07a69d4Peter Qiu * When set to true, the device should check AAA (Authentication, Authorization, 119444dc5d099788e5aa0fd0e664fd952fbb07a69d4Peter Qiu * and Accounting) server's certificate during EAP (Extensible Authentication 120444dc5d099788e5aa0fd0e664fd952fbb07a69d4Peter Qiu * Protocol) authentication. 121444dc5d099788e5aa0fd0e664fd952fbb07a69d4Peter Qiu */ 122da8a67e8a606ebd49a724a18d3581b62121b532cPeter Qiu private boolean mCheckAaaServerCertStatus = false; 123a9f9889218ac972706830440990a59cbee685976Peter Qiu /** 124a9f9889218ac972706830440990a59cbee685976Peter Qiu * @hide 125a9f9889218ac972706830440990a59cbee685976Peter Qiu */ 126da8a67e8a606ebd49a724a18d3581b62121b532cPeter Qiu public void setCheckAaaServerCertStatus(boolean checkAaaServerCertStatus) { 127da8a67e8a606ebd49a724a18d3581b62121b532cPeter Qiu mCheckAaaServerCertStatus = checkAaaServerCertStatus; 128aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu } 129a9f9889218ac972706830440990a59cbee685976Peter Qiu /** 130a9f9889218ac972706830440990a59cbee685976Peter Qiu * @hide 131a9f9889218ac972706830440990a59cbee685976Peter Qiu */ 132701a4b55c92817c84a77df84234946dbaac71dbaPeter Qiu public boolean getCheckAaaServerCertStatus() { 133da8a67e8a606ebd49a724a18d3581b62121b532cPeter Qiu return mCheckAaaServerCertStatus; 134aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu } 135444dc5d099788e5aa0fd0e664fd952fbb07a69d4Peter Qiu 136444dc5d099788e5aa0fd0e664fd952fbb07a69d4Peter Qiu /** 137e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu * Username-password based credential. 138e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu * Contains the fields under PerProviderSubscription/Credential/UsernamePassword subtree. 139e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu */ 140e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu public static final class UserCredential implements Parcelable { 141e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu /** 142a25d717de870895be52e81b585a8484fff0c6109Peter Qiu * Maximum string length for username. Refer to Credential/UsernamePassword/Username 143a25d717de870895be52e81b585a8484fff0c6109Peter Qiu * node in Hotspot 2.0 Release 2 Technical Specification Section 9.1 for more info. 144a25d717de870895be52e81b585a8484fff0c6109Peter Qiu */ 145444dc5d099788e5aa0fd0e664fd952fbb07a69d4Peter Qiu private static final int MAX_USERNAME_BYTES = 63; 146a25d717de870895be52e81b585a8484fff0c6109Peter Qiu 147a25d717de870895be52e81b585a8484fff0c6109Peter Qiu /** 148a25d717de870895be52e81b585a8484fff0c6109Peter Qiu * Maximum string length for password. Refer to Credential/UsernamePassword/Password 149a25d717de870895be52e81b585a8484fff0c6109Peter Qiu * in Hotspot 2.0 Release 2 Technical Specification Section 9.1 for more info. 150a25d717de870895be52e81b585a8484fff0c6109Peter Qiu */ 151444dc5d099788e5aa0fd0e664fd952fbb07a69d4Peter Qiu private static final int MAX_PASSWORD_BYTES = 255; 152a25d717de870895be52e81b585a8484fff0c6109Peter Qiu 153a25d717de870895be52e81b585a8484fff0c6109Peter Qiu /** 154f8dbd216c8d49473b195077f3d3519fc3f7fde18Peter Qiu * Supported authentication methods. 155f8dbd216c8d49473b195077f3d3519fc3f7fde18Peter Qiu * @hide 156f8dbd216c8d49473b195077f3d3519fc3f7fde18Peter Qiu */ 157f8dbd216c8d49473b195077f3d3519fc3f7fde18Peter Qiu public static final String AUTH_METHOD_PAP = "PAP"; 158f8dbd216c8d49473b195077f3d3519fc3f7fde18Peter Qiu /** @hide */ 159f8dbd216c8d49473b195077f3d3519fc3f7fde18Peter Qiu public static final String AUTH_METHOD_MSCHAP = "MS-CHAP"; 160f8dbd216c8d49473b195077f3d3519fc3f7fde18Peter Qiu /** @hide */ 161f8dbd216c8d49473b195077f3d3519fc3f7fde18Peter Qiu public static final String AUTH_METHOD_MSCHAPV2 = "MS-CHAP-V2"; 162f8dbd216c8d49473b195077f3d3519fc3f7fde18Peter Qiu 163f8dbd216c8d49473b195077f3d3519fc3f7fde18Peter Qiu /** 164a25d717de870895be52e81b585a8484fff0c6109Peter Qiu * Supported Non-EAP inner methods. Refer to 165a25d717de870895be52e81b585a8484fff0c6109Peter Qiu * Credential/UsernamePassword/EAPMethod/InnerEAPType in Hotspot 2.0 Release 2 Technical 166a25d717de870895be52e81b585a8484fff0c6109Peter Qiu * Specification Section 9.1 for more info. 167a25d717de870895be52e81b585a8484fff0c6109Peter Qiu */ 168f8dbd216c8d49473b195077f3d3519fc3f7fde18Peter Qiu private static final Set<String> SUPPORTED_AUTH = new HashSet<String>( 169f8dbd216c8d49473b195077f3d3519fc3f7fde18Peter Qiu Arrays.asList(AUTH_METHOD_PAP, AUTH_METHOD_MSCHAP, AUTH_METHOD_MSCHAPV2)); 170a25d717de870895be52e81b585a8484fff0c6109Peter Qiu 171a25d717de870895be52e81b585a8484fff0c6109Peter Qiu /** 172e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu * Username of the credential. 173e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu */ 174aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu private String mUsername = null; 175e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu /** 176e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * Set the username associated with this user credential. 177e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * 178e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * @param username The username to set to 179e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu */ 180aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu public void setUsername(String username) { 181aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu mUsername = username; 182aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu } 183e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu /** 184e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * Get the username associated with this user credential. 185e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * 186e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * @return the username associated with this user credential 187e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu */ 188aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu public String getUsername() { 189aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu return mUsername; 190aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu } 191e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu 192e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu /** 193e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu * Base64-encoded password. 194e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu */ 195aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu private String mPassword = null; 196e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu /** 197e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * Set the Base64-encoded password associated with this user credential. 198e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * 199e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * @param password The password to set to 200e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu */ 201aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu public void setPassword(String password) { 202aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu mPassword = password; 203aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu } 204e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu /** 205e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * Get the Base64-encoded password associated with this user credential. 206e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * 207e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * @return the Base64-encoded password associated with this user credential 208e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu */ 209aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu public String getPassword() { 210aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu return mPassword; 211aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu } 212e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu 213e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu /** 214444dc5d099788e5aa0fd0e664fd952fbb07a69d4Peter Qiu * Flag indicating if the password is machine managed. 215444dc5d099788e5aa0fd0e664fd952fbb07a69d4Peter Qiu */ 216aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu private boolean mMachineManaged = false; 217a9f9889218ac972706830440990a59cbee685976Peter Qiu /** 218a9f9889218ac972706830440990a59cbee685976Peter Qiu * @hide 219a9f9889218ac972706830440990a59cbee685976Peter Qiu */ 220aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu public void setMachineManaged(boolean machineManaged) { 221aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu mMachineManaged = machineManaged; 222aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu } 223a9f9889218ac972706830440990a59cbee685976Peter Qiu /** 224a9f9889218ac972706830440990a59cbee685976Peter Qiu * @hide 225a9f9889218ac972706830440990a59cbee685976Peter Qiu */ 226aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu public boolean getMachineManaged() { 227aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu return mMachineManaged; 228aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu } 229444dc5d099788e5aa0fd0e664fd952fbb07a69d4Peter Qiu 230444dc5d099788e5aa0fd0e664fd952fbb07a69d4Peter Qiu /** 231444dc5d099788e5aa0fd0e664fd952fbb07a69d4Peter Qiu * The name of the application used to generate the password. 232444dc5d099788e5aa0fd0e664fd952fbb07a69d4Peter Qiu */ 233aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu private String mSoftTokenApp = null; 234a9f9889218ac972706830440990a59cbee685976Peter Qiu /** 235a9f9889218ac972706830440990a59cbee685976Peter Qiu * @hide 236a9f9889218ac972706830440990a59cbee685976Peter Qiu */ 237aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu public void setSoftTokenApp(String softTokenApp) { 238aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu mSoftTokenApp = softTokenApp; 239aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu } 240a9f9889218ac972706830440990a59cbee685976Peter Qiu /** 241a9f9889218ac972706830440990a59cbee685976Peter Qiu * @hide 242a9f9889218ac972706830440990a59cbee685976Peter Qiu */ 243aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu public String getSoftTokenApp() { 244aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu return mSoftTokenApp; 245aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu } 246444dc5d099788e5aa0fd0e664fd952fbb07a69d4Peter Qiu 247444dc5d099788e5aa0fd0e664fd952fbb07a69d4Peter Qiu /** 248444dc5d099788e5aa0fd0e664fd952fbb07a69d4Peter Qiu * Flag indicating if this credential is usable on other mobile devices as well. 249444dc5d099788e5aa0fd0e664fd952fbb07a69d4Peter Qiu */ 250aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu private boolean mAbleToShare = false; 251a9f9889218ac972706830440990a59cbee685976Peter Qiu /** 252a9f9889218ac972706830440990a59cbee685976Peter Qiu * @hide 253a9f9889218ac972706830440990a59cbee685976Peter Qiu */ 254aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu public void setAbleToShare(boolean ableToShare) { 255aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu mAbleToShare = ableToShare; 256aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu } 257a9f9889218ac972706830440990a59cbee685976Peter Qiu /** 258a9f9889218ac972706830440990a59cbee685976Peter Qiu * @hide 259a9f9889218ac972706830440990a59cbee685976Peter Qiu */ 260aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu public boolean getAbleToShare() { 261aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu return mAbleToShare; 262aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu } 263444dc5d099788e5aa0fd0e664fd952fbb07a69d4Peter Qiu 264444dc5d099788e5aa0fd0e664fd952fbb07a69d4Peter Qiu /** 265e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu * EAP (Extensible Authentication Protocol) method type. 266e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * Refer to 267e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * <a href="http://www.iana.org/assignments/eap-numbers/eap-numbers.xml#eap-numbers-4"> 268e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * EAP Numbers</a> for valid values. 269e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu * Using Integer.MIN_VALUE to indicate unset value. 270e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu */ 271aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu private int mEapType = Integer.MIN_VALUE; 272e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu /** 273e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * Set the EAP (Extensible Authentication Protocol) method type associated with this 274e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * user credential. 275e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * Refer to 276e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * <a href="http://www.iana.org/assignments/eap-numbers/eap-numbers.xml#eap-numbers-4"> 277e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * EAP Numbers</a> for valid values. 278e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * 279e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * @param eapType The EAP method type associated with this user credential 280e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu */ 281aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu public void setEapType(int eapType) { 282aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu mEapType = eapType; 283aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu } 284e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu /** 285e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * Get the EAP (Extensible Authentication Protocol) method type associated with this 286e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * user credential. 287e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * 288e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * @return EAP method type 289e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu */ 290aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu public int getEapType() { 291aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu return mEapType; 292aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu } 293e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu 294e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu /** 295e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu * Non-EAP inner authentication method. 296e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu */ 297aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu private String mNonEapInnerMethod = null; 298e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu /** 299e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * Set the inner non-EAP method associated with this user credential. 300e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * 301e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * @param nonEapInnerMethod The non-EAP inner method to set to 302e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu */ 303aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu public void setNonEapInnerMethod(String nonEapInnerMethod) { 304aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu mNonEapInnerMethod = nonEapInnerMethod; 305aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu } 306e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu /** 307e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * Get the inner non-EAP method associated with this user credential. 308e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * 309e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * @return Non-EAP inner method associated with this user credential 310e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu */ 311aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu public String getNonEapInnerMethod() { 312aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu return mNonEapInnerMethod; 313aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu } 314e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu 315a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu /** 316a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu * Constructor for creating UserCredential with default values. 317a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu */ 318a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu public UserCredential() {} 319a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu 320a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu /** 321a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu * Copy constructor. 322a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu * 323a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu * @param source The source to copy from 324a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu */ 325a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu public UserCredential(UserCredential source) { 326a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu if (source != null) { 327aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu mUsername = source.mUsername; 328aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu mPassword = source.mPassword; 329aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu mMachineManaged = source.mMachineManaged; 330aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu mSoftTokenApp = source.mSoftTokenApp; 331aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu mAbleToShare = source.mAbleToShare; 332aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu mEapType = source.mEapType; 333aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu mNonEapInnerMethod = source.mNonEapInnerMethod; 334a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu } 335a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu } 336a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu 337e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu @Override 338e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu public int describeContents() { 339e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu return 0; 340e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu } 341e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu 342e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu @Override 343e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu public void writeToParcel(Parcel dest, int flags) { 344aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu dest.writeString(mUsername); 345aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu dest.writeString(mPassword); 346aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu dest.writeInt(mMachineManaged ? 1 : 0); 347aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu dest.writeString(mSoftTokenApp); 348aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu dest.writeInt(mAbleToShare ? 1 : 0); 349aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu dest.writeInt(mEapType); 350aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu dest.writeString(mNonEapInnerMethod); 351e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu } 352e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu 353e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu @Override 354e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu public boolean equals(Object thatObject) { 355e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu if (this == thatObject) { 356e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu return true; 357e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu } 358e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu if (!(thatObject instanceof UserCredential)) { 359e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu return false; 360e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu } 361e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu 362e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu UserCredential that = (UserCredential) thatObject; 363aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu return TextUtils.equals(mUsername, that.mUsername) 364aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu && TextUtils.equals(mPassword, that.mPassword) 365aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu && mMachineManaged == that.mMachineManaged 366aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu && TextUtils.equals(mSoftTokenApp, that.mSoftTokenApp) 367aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu && mAbleToShare == that.mAbleToShare 368aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu && mEapType == that.mEapType 369aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu && TextUtils.equals(mNonEapInnerMethod, that.mNonEapInnerMethod); 370e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu } 371e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu 372ddafc73496e3bab135ac7249bfb3cf4d871e5cf2Peter Qiu @Override 373ddafc73496e3bab135ac7249bfb3cf4d871e5cf2Peter Qiu public int hashCode() { 374ddafc73496e3bab135ac7249bfb3cf4d871e5cf2Peter Qiu return Objects.hash(mUsername, mPassword, mMachineManaged, mSoftTokenApp, 375ddafc73496e3bab135ac7249bfb3cf4d871e5cf2Peter Qiu mAbleToShare, mEapType, mNonEapInnerMethod); 376ddafc73496e3bab135ac7249bfb3cf4d871e5cf2Peter Qiu } 377ddafc73496e3bab135ac7249bfb3cf4d871e5cf2Peter Qiu 37889537734e19fac6947ee14a1b912c5c135042837Peter Qiu @Override 37989537734e19fac6947ee14a1b912c5c135042837Peter Qiu public String toString() { 38089537734e19fac6947ee14a1b912c5c135042837Peter Qiu StringBuilder builder = new StringBuilder(); 38189537734e19fac6947ee14a1b912c5c135042837Peter Qiu builder.append("Username: ").append(mUsername).append("\n"); 38289537734e19fac6947ee14a1b912c5c135042837Peter Qiu builder.append("MachineManaged: ").append(mMachineManaged).append("\n"); 38389537734e19fac6947ee14a1b912c5c135042837Peter Qiu builder.append("SoftTokenApp: ").append(mSoftTokenApp).append("\n"); 38489537734e19fac6947ee14a1b912c5c135042837Peter Qiu builder.append("AbleToShare: ").append(mAbleToShare).append("\n"); 38589537734e19fac6947ee14a1b912c5c135042837Peter Qiu builder.append("EAPType: ").append(mEapType).append("\n"); 38689537734e19fac6947ee14a1b912c5c135042837Peter Qiu builder.append("AuthMethod: ").append(mNonEapInnerMethod).append("\n"); 38789537734e19fac6947ee14a1b912c5c135042837Peter Qiu return builder.toString(); 38889537734e19fac6947ee14a1b912c5c135042837Peter Qiu } 38989537734e19fac6947ee14a1b912c5c135042837Peter Qiu 390a25d717de870895be52e81b585a8484fff0c6109Peter Qiu /** 391a25d717de870895be52e81b585a8484fff0c6109Peter Qiu * Validate the configuration data. 392a25d717de870895be52e81b585a8484fff0c6109Peter Qiu * 393a25d717de870895be52e81b585a8484fff0c6109Peter Qiu * @return true on success or false on failure 394b5ca6f36b54023f6336740cf3bff79c08ecb6609Peter Qiu * @hide 395a25d717de870895be52e81b585a8484fff0c6109Peter Qiu */ 396a25d717de870895be52e81b585a8484fff0c6109Peter Qiu public boolean validate() { 397aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu if (TextUtils.isEmpty(mUsername)) { 398a25d717de870895be52e81b585a8484fff0c6109Peter Qiu Log.d(TAG, "Missing username"); 399a25d717de870895be52e81b585a8484fff0c6109Peter Qiu return false; 400a25d717de870895be52e81b585a8484fff0c6109Peter Qiu } 401aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu if (mUsername.getBytes(StandardCharsets.UTF_8).length > MAX_USERNAME_BYTES) { 402444dc5d099788e5aa0fd0e664fd952fbb07a69d4Peter Qiu Log.d(TAG, "username exceeding maximum length: " 403aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu + mUsername.getBytes(StandardCharsets.UTF_8).length); 404a25d717de870895be52e81b585a8484fff0c6109Peter Qiu return false; 405a25d717de870895be52e81b585a8484fff0c6109Peter Qiu } 406a25d717de870895be52e81b585a8484fff0c6109Peter Qiu 407aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu if (TextUtils.isEmpty(mPassword)) { 408a25d717de870895be52e81b585a8484fff0c6109Peter Qiu Log.d(TAG, "Missing password"); 409a25d717de870895be52e81b585a8484fff0c6109Peter Qiu return false; 410a25d717de870895be52e81b585a8484fff0c6109Peter Qiu } 411aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu if (mPassword.getBytes(StandardCharsets.UTF_8).length > MAX_PASSWORD_BYTES) { 412444dc5d099788e5aa0fd0e664fd952fbb07a69d4Peter Qiu Log.d(TAG, "password exceeding maximum length: " 413aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu + mPassword.getBytes(StandardCharsets.UTF_8).length); 414a25d717de870895be52e81b585a8484fff0c6109Peter Qiu return false; 415a25d717de870895be52e81b585a8484fff0c6109Peter Qiu } 416a25d717de870895be52e81b585a8484fff0c6109Peter Qiu 417a25d717de870895be52e81b585a8484fff0c6109Peter Qiu // Only supports EAP-TTLS for user credential. 418aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu if (mEapType != EAPConstants.EAP_TTLS) { 419aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu Log.d(TAG, "Invalid EAP Type for user credential: " + mEapType); 420a25d717de870895be52e81b585a8484fff0c6109Peter Qiu return false; 421a25d717de870895be52e81b585a8484fff0c6109Peter Qiu } 422a25d717de870895be52e81b585a8484fff0c6109Peter Qiu 423a25d717de870895be52e81b585a8484fff0c6109Peter Qiu // Verify Non-EAP inner method for EAP-TTLS. 424aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu if (!SUPPORTED_AUTH.contains(mNonEapInnerMethod)) { 425aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu Log.d(TAG, "Invalid non-EAP inner method for EAP-TTLS: " + mNonEapInnerMethod); 426a25d717de870895be52e81b585a8484fff0c6109Peter Qiu return false; 427a25d717de870895be52e81b585a8484fff0c6109Peter Qiu } 428a25d717de870895be52e81b585a8484fff0c6109Peter Qiu return true; 429a25d717de870895be52e81b585a8484fff0c6109Peter Qiu } 430a25d717de870895be52e81b585a8484fff0c6109Peter Qiu 431e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu public static final Creator<UserCredential> CREATOR = 432e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu new Creator<UserCredential>() { 433e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu @Override 434e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu public UserCredential createFromParcel(Parcel in) { 435e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu UserCredential userCredential = new UserCredential(); 436aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu userCredential.setUsername(in.readString()); 437aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu userCredential.setPassword(in.readString()); 438aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu userCredential.setMachineManaged(in.readInt() != 0); 439aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu userCredential.setSoftTokenApp(in.readString()); 440aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu userCredential.setAbleToShare(in.readInt() != 0); 441aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu userCredential.setEapType(in.readInt()); 442aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu userCredential.setNonEapInnerMethod(in.readString()); 443e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu return userCredential; 444e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu } 445e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu 446e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu @Override 447e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu public UserCredential[] newArray(int size) { 448e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu return new UserCredential[size]; 449e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu } 450e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu }; 451e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu } 452aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu private UserCredential mUserCredential = null; 453e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu /** 454e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * Set the user credential information. 455e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * 456e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * @param userCredential The user credential to set to 457e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu */ 458aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu public void setUserCredential(UserCredential userCredential) { 459aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu mUserCredential = userCredential; 460aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu } 461e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu /** 462e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * Get the user credential information. 463e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * 464e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * @return user credential information 465e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu */ 466aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu public UserCredential getUserCredential() { 467aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu return mUserCredential; 468aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu } 469e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu 470e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu /** 471a25d717de870895be52e81b585a8484fff0c6109Peter Qiu * Certificate based credential. This is used for EAP-TLS. 472e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu * Contains fields under PerProviderSubscription/Credential/DigitalCertificate subtree. 473e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu */ 474e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu public static final class CertificateCredential implements Parcelable { 475e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu /** 476a25d717de870895be52e81b585a8484fff0c6109Peter Qiu * Supported certificate types. 477f8dbd216c8d49473b195077f3d3519fc3f7fde18Peter Qiu * @hide 478a25d717de870895be52e81b585a8484fff0c6109Peter Qiu */ 479f8dbd216c8d49473b195077f3d3519fc3f7fde18Peter Qiu public static final String CERT_TYPE_X509V3 = "x509v3"; 480a25d717de870895be52e81b585a8484fff0c6109Peter Qiu 481a25d717de870895be52e81b585a8484fff0c6109Peter Qiu /** 482a25d717de870895be52e81b585a8484fff0c6109Peter Qiu * Certificate SHA-256 fingerprint length. 483a25d717de870895be52e81b585a8484fff0c6109Peter Qiu */ 484a25d717de870895be52e81b585a8484fff0c6109Peter Qiu private static final int CERT_SHA256_FINGER_PRINT_LENGTH = 32; 485a25d717de870895be52e81b585a8484fff0c6109Peter Qiu 486a25d717de870895be52e81b585a8484fff0c6109Peter Qiu /** 487a25d717de870895be52e81b585a8484fff0c6109Peter Qiu * Certificate type. 488e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu */ 489aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu private String mCertType = null; 490e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu /** 491e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * Set the certificate type associated with this certificate credential. 492e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * 493e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * @param certType The certificate type to set to 494e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu */ 495aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu public void setCertType(String certType) { 496aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu mCertType = certType; 497aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu } 498e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu /** 499e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * Get the certificate type associated with this certificate credential. 500e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * 501e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * @return certificate type 502e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu */ 503aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu public String getCertType() { 504aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu return mCertType; 505aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu } 506e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu 507e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu /** 508e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu * The SHA-256 fingerprint of the certificate. 509e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu */ 510aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu private byte[] mCertSha256Fingerprint = null; 511e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu /** 512e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * Set the certificate SHA-256 fingerprint associated with this certificate credential. 513e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * 514e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * @param certSha256Fingerprint The certificate fingerprint to set to 515e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu */ 516aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu public void setCertSha256Fingerprint(byte[] certSha256Fingerprint) { 517aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu mCertSha256Fingerprint = certSha256Fingerprint; 518aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu } 519e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu /** 520e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * Get the certificate SHA-256 fingerprint associated with this certificate credential. 521e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * 522e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * @return certificate SHA-256 fingerprint 523e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu */ 524aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu public byte[] getCertSha256Fingerprint() { 525aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu return mCertSha256Fingerprint; 526aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu } 527e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu 528a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu /** 529a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu * Constructor for creating CertificateCredential with default values. 530a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu */ 531a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu public CertificateCredential() {} 532a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu 533a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu /** 534a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu * Copy constructor. 535a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu * 536a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu * @param source The source to copy from 537a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu */ 538a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu public CertificateCredential(CertificateCredential source) { 539a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu if (source != null) { 540aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu mCertType = source.mCertType; 541aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu if (source.mCertSha256Fingerprint != null) { 542aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu mCertSha256Fingerprint = Arrays.copyOf(source.mCertSha256Fingerprint, 543aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu source.mCertSha256Fingerprint.length); 544a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu } 545a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu } 546a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu } 547a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu 548e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu @Override 549e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu public int describeContents() { 550e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu return 0; 551e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu } 552e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu 553e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu @Override 554e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu public void writeToParcel(Parcel dest, int flags) { 555aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu dest.writeString(mCertType); 556aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu dest.writeByteArray(mCertSha256Fingerprint); 557e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu } 558e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu 559e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu @Override 560e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu public boolean equals(Object thatObject) { 561e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu if (this == thatObject) { 562e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu return true; 563e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu } 564e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu if (!(thatObject instanceof CertificateCredential)) { 565e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu return false; 566e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu } 567e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu 568e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu CertificateCredential that = (CertificateCredential) thatObject; 569aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu return TextUtils.equals(mCertType, that.mCertType) 570aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu && Arrays.equals(mCertSha256Fingerprint, that.mCertSha256Fingerprint); 571e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu } 572e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu 573ddafc73496e3bab135ac7249bfb3cf4d871e5cf2Peter Qiu @Override 574ddafc73496e3bab135ac7249bfb3cf4d871e5cf2Peter Qiu public int hashCode() { 575ddafc73496e3bab135ac7249bfb3cf4d871e5cf2Peter Qiu return Objects.hash(mCertType, mCertSha256Fingerprint); 576ddafc73496e3bab135ac7249bfb3cf4d871e5cf2Peter Qiu } 577ddafc73496e3bab135ac7249bfb3cf4d871e5cf2Peter Qiu 57889537734e19fac6947ee14a1b912c5c135042837Peter Qiu @Override 57989537734e19fac6947ee14a1b912c5c135042837Peter Qiu public String toString() { 58089537734e19fac6947ee14a1b912c5c135042837Peter Qiu return "CertificateType: " + mCertType + "\n"; 58189537734e19fac6947ee14a1b912c5c135042837Peter Qiu } 58289537734e19fac6947ee14a1b912c5c135042837Peter Qiu 583a25d717de870895be52e81b585a8484fff0c6109Peter Qiu /** 584a25d717de870895be52e81b585a8484fff0c6109Peter Qiu * Validate the configuration data. 585a25d717de870895be52e81b585a8484fff0c6109Peter Qiu * 586a25d717de870895be52e81b585a8484fff0c6109Peter Qiu * @return true on success or false on failure 587b5ca6f36b54023f6336740cf3bff79c08ecb6609Peter Qiu * @hide 588a25d717de870895be52e81b585a8484fff0c6109Peter Qiu */ 589a25d717de870895be52e81b585a8484fff0c6109Peter Qiu public boolean validate() { 590aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu if (!TextUtils.equals(CERT_TYPE_X509V3, mCertType)) { 591aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu Log.d(TAG, "Unsupported certificate type: " + mCertType); 592a25d717de870895be52e81b585a8484fff0c6109Peter Qiu return false; 593a25d717de870895be52e81b585a8484fff0c6109Peter Qiu } 594aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu if (mCertSha256Fingerprint == null 595aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu || mCertSha256Fingerprint.length != CERT_SHA256_FINGER_PRINT_LENGTH) { 596a25d717de870895be52e81b585a8484fff0c6109Peter Qiu Log.d(TAG, "Invalid SHA-256 fingerprint"); 597a25d717de870895be52e81b585a8484fff0c6109Peter Qiu return false; 598a25d717de870895be52e81b585a8484fff0c6109Peter Qiu } 599a25d717de870895be52e81b585a8484fff0c6109Peter Qiu return true; 600a25d717de870895be52e81b585a8484fff0c6109Peter Qiu } 601a25d717de870895be52e81b585a8484fff0c6109Peter Qiu 602e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu public static final Creator<CertificateCredential> CREATOR = 603e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu new Creator<CertificateCredential>() { 604e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu @Override 605e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu public CertificateCredential createFromParcel(Parcel in) { 606e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu CertificateCredential certCredential = new CertificateCredential(); 607aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu certCredential.setCertType(in.readString()); 608aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu certCredential.setCertSha256Fingerprint(in.createByteArray()); 609e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu return certCredential; 610e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu } 611e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu 612e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu @Override 613e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu public CertificateCredential[] newArray(int size) { 614e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu return new CertificateCredential[size]; 615e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu } 616e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu }; 617e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu } 618aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu private CertificateCredential mCertCredential = null; 619e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu /** 620e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * Set the certificate credential information. 621e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * 622e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * @param certCredential The certificate credential to set to 623e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu */ 624aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu public void setCertCredential(CertificateCredential certCredential) { 625aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu mCertCredential = certCredential; 626aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu } 627e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu /** 628e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * Get the certificate credential information. 629e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * 630e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * @return certificate credential information 631e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu */ 632aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu public CertificateCredential getCertCredential() { 633aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu return mCertCredential; 634aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu } 635e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu 636e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu /** 637e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu * SIM (Subscriber Identify Module) based credential. 638e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu * Contains fields under PerProviderSubscription/Credential/SIM subtree. 639e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu */ 640e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu public static final class SimCredential implements Parcelable { 641e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu /** 642a25d717de870895be52e81b585a8484fff0c6109Peter Qiu * Maximum string length for IMSI. 643a25d717de870895be52e81b585a8484fff0c6109Peter Qiu */ 644aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu private static final int MAX_IMSI_LENGTH = 15; 645a25d717de870895be52e81b585a8484fff0c6109Peter Qiu 646a25d717de870895be52e81b585a8484fff0c6109Peter Qiu /** 647a25d717de870895be52e81b585a8484fff0c6109Peter Qiu * International Mobile Subscriber Identity, is used to identify the user 648a25d717de870895be52e81b585a8484fff0c6109Peter Qiu * of a cellular network and is a unique identification associated with all 649a25d717de870895be52e81b585a8484fff0c6109Peter Qiu * cellular networks 650e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu */ 651aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu private String mImsi = null; 652e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu /** 653e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * Set the IMSI (International Mobile Subscriber Identity) associated with this SIM 654e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * credential. 655e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * 656e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * @param imsi The IMSI to set to 657e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu */ 658aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu public void setImsi(String imsi) { 659aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu mImsi = imsi; 660aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu } 661e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu /** 662e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * Get the IMSI (International Mobile Subscriber Identity) associated with this SIM 663e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * credential. 664e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * 665e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * @return IMSI associated with this SIM credential 666e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu */ 667aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu public String getImsi() { 668aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu return mImsi; 669aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu } 670e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu 671e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu /** 672e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu * EAP (Extensible Authentication Protocol) method type for using SIM credential. 673e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu * Refer to http://www.iana.org/assignments/eap-numbers/eap-numbers.xml#eap-numbers-4 674e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu * for valid values. 675e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu * Using Integer.MIN_VALUE to indicate unset value. 676e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu */ 677aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu private int mEapType = Integer.MIN_VALUE; 678e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu /** 679e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * Set the EAP (Extensible Authentication Protocol) method type associated with this 680e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * SIM credential. 681e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * 682e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * @param eapType The EAP method type to set to 683e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu */ 684aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu public void setEapType(int eapType) { 685aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu mEapType = eapType; 686aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu } 687e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu /** 688e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * Get the EAP (Extensible Authentication Protocol) method type associated with this 689e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * SIM credential. 690e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * 691e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * @return EAP method type associated with this SIM credential 692e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu */ 693aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu public int getEapType() { 694aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu return mEapType; 695aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu } 696e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu 697a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu /** 698a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu * Constructor for creating SimCredential with default values. 699a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu */ 700a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu public SimCredential() {} 701a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu 702a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu /** 703a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu * Copy constructor 704a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu * 705a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu * @param source The source to copy from 706a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu */ 707a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu public SimCredential(SimCredential source) { 708a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu if (source != null) { 709aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu mImsi = source.mImsi; 710aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu mEapType = source.mEapType; 711a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu } 712a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu } 713a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu 714e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu @Override 715e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu public int describeContents() { 716e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu return 0; 717e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu } 718e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu 719e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu @Override 720e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu public boolean equals(Object thatObject) { 721e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu if (this == thatObject) { 722e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu return true; 723e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu } 724e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu if (!(thatObject instanceof SimCredential)) { 725e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu return false; 726e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu } 727e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu 728e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu SimCredential that = (SimCredential) thatObject; 729aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu return TextUtils.equals(mImsi, that.mImsi) 730aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu && mEapType == that.mEapType; 731e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu } 732e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu 733e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu @Override 734ddafc73496e3bab135ac7249bfb3cf4d871e5cf2Peter Qiu public int hashCode() { 735ddafc73496e3bab135ac7249bfb3cf4d871e5cf2Peter Qiu return Objects.hash(mImsi, mEapType); 736ddafc73496e3bab135ac7249bfb3cf4d871e5cf2Peter Qiu } 737ddafc73496e3bab135ac7249bfb3cf4d871e5cf2Peter Qiu 738ddafc73496e3bab135ac7249bfb3cf4d871e5cf2Peter Qiu @Override 73989537734e19fac6947ee14a1b912c5c135042837Peter Qiu public String toString() { 74089537734e19fac6947ee14a1b912c5c135042837Peter Qiu StringBuilder builder = new StringBuilder(); 74189537734e19fac6947ee14a1b912c5c135042837Peter Qiu builder.append("IMSI: ").append(mImsi).append("\n"); 74289537734e19fac6947ee14a1b912c5c135042837Peter Qiu builder.append("EAPType: ").append(mEapType).append("\n"); 74389537734e19fac6947ee14a1b912c5c135042837Peter Qiu return builder.toString(); 74489537734e19fac6947ee14a1b912c5c135042837Peter Qiu } 74589537734e19fac6947ee14a1b912c5c135042837Peter Qiu 74689537734e19fac6947ee14a1b912c5c135042837Peter Qiu @Override 747e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu public void writeToParcel(Parcel dest, int flags) { 748aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu dest.writeString(mImsi); 749aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu dest.writeInt(mEapType); 750e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu } 751e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu 752a25d717de870895be52e81b585a8484fff0c6109Peter Qiu /** 753a25d717de870895be52e81b585a8484fff0c6109Peter Qiu * Validate the configuration data. 754a25d717de870895be52e81b585a8484fff0c6109Peter Qiu * 755a25d717de870895be52e81b585a8484fff0c6109Peter Qiu * @return true on success or false on failure 756b5ca6f36b54023f6336740cf3bff79c08ecb6609Peter Qiu * @hide 757a25d717de870895be52e81b585a8484fff0c6109Peter Qiu */ 758a25d717de870895be52e81b585a8484fff0c6109Peter Qiu public boolean validate() { 759a25d717de870895be52e81b585a8484fff0c6109Peter Qiu // Note: this only validate the format of IMSI string itself. Additional verification 760a25d717de870895be52e81b585a8484fff0c6109Peter Qiu // will be done by WifiService at the time of provisioning to verify against the IMSI 761a25d717de870895be52e81b585a8484fff0c6109Peter Qiu // of the SIM card installed in the device. 762a25d717de870895be52e81b585a8484fff0c6109Peter Qiu if (!verifyImsi()) { 763a25d717de870895be52e81b585a8484fff0c6109Peter Qiu return false; 764a25d717de870895be52e81b585a8484fff0c6109Peter Qiu } 765aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu if (mEapType != EAPConstants.EAP_SIM && mEapType != EAPConstants.EAP_AKA 766aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu && mEapType != EAPConstants.EAP_AKA_PRIME) { 767aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu Log.d(TAG, "Invalid EAP Type for SIM credential: " + mEapType); 768a25d717de870895be52e81b585a8484fff0c6109Peter Qiu return false; 769a25d717de870895be52e81b585a8484fff0c6109Peter Qiu } 770a25d717de870895be52e81b585a8484fff0c6109Peter Qiu return true; 771a25d717de870895be52e81b585a8484fff0c6109Peter Qiu } 772a25d717de870895be52e81b585a8484fff0c6109Peter Qiu 773e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu public static final Creator<SimCredential> CREATOR = 774e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu new Creator<SimCredential>() { 775e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu @Override 776e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu public SimCredential createFromParcel(Parcel in) { 777e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu SimCredential simCredential = new SimCredential(); 778aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu simCredential.setImsi(in.readString()); 779aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu simCredential.setEapType(in.readInt()); 780e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu return simCredential; 781e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu } 782e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu 783e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu @Override 784e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu public SimCredential[] newArray(int size) { 785e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu return new SimCredential[size]; 786e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu } 787e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu }; 788a25d717de870895be52e81b585a8484fff0c6109Peter Qiu 789a25d717de870895be52e81b585a8484fff0c6109Peter Qiu /** 790a25d717de870895be52e81b585a8484fff0c6109Peter Qiu * Verify the IMSI (International Mobile Subscriber Identity) string. The string 791a25d717de870895be52e81b585a8484fff0c6109Peter Qiu * should contain zero or more numeric digits, and might ends with a "*" for prefix 792a25d717de870895be52e81b585a8484fff0c6109Peter Qiu * matching. 793a25d717de870895be52e81b585a8484fff0c6109Peter Qiu * 794a25d717de870895be52e81b585a8484fff0c6109Peter Qiu * @return true if IMSI is valid, false otherwise. 795a25d717de870895be52e81b585a8484fff0c6109Peter Qiu */ 796a25d717de870895be52e81b585a8484fff0c6109Peter Qiu private boolean verifyImsi() { 797aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu if (TextUtils.isEmpty(mImsi)) { 798a25d717de870895be52e81b585a8484fff0c6109Peter Qiu Log.d(TAG, "Missing IMSI"); 799a25d717de870895be52e81b585a8484fff0c6109Peter Qiu return false; 800a25d717de870895be52e81b585a8484fff0c6109Peter Qiu } 801aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu if (mImsi.length() > MAX_IMSI_LENGTH) { 802aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu Log.d(TAG, "IMSI exceeding maximum length: " + mImsi.length()); 803a25d717de870895be52e81b585a8484fff0c6109Peter Qiu return false; 804a25d717de870895be52e81b585a8484fff0c6109Peter Qiu } 805a25d717de870895be52e81b585a8484fff0c6109Peter Qiu 806a25d717de870895be52e81b585a8484fff0c6109Peter Qiu // Locate the first non-digit character. 807a25d717de870895be52e81b585a8484fff0c6109Peter Qiu int nonDigit; 808a25d717de870895be52e81b585a8484fff0c6109Peter Qiu char stopChar = '\0'; 809aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu for (nonDigit = 0; nonDigit < mImsi.length(); nonDigit++) { 810aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu stopChar = mImsi.charAt(nonDigit); 811a25d717de870895be52e81b585a8484fff0c6109Peter Qiu if (stopChar < '0' || stopChar > '9') { 812a25d717de870895be52e81b585a8484fff0c6109Peter Qiu break; 813a25d717de870895be52e81b585a8484fff0c6109Peter Qiu } 814a25d717de870895be52e81b585a8484fff0c6109Peter Qiu } 815a25d717de870895be52e81b585a8484fff0c6109Peter Qiu 816aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu if (nonDigit == mImsi.length()) { 817a25d717de870895be52e81b585a8484fff0c6109Peter Qiu return true; 818a25d717de870895be52e81b585a8484fff0c6109Peter Qiu } 819aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu else if (nonDigit == mImsi.length()-1 && stopChar == '*') { 820a25d717de870895be52e81b585a8484fff0c6109Peter Qiu // Prefix matching. 821a25d717de870895be52e81b585a8484fff0c6109Peter Qiu return true; 822a25d717de870895be52e81b585a8484fff0c6109Peter Qiu } 823a25d717de870895be52e81b585a8484fff0c6109Peter Qiu return false; 824a25d717de870895be52e81b585a8484fff0c6109Peter Qiu } 825e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu } 826aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu private SimCredential mSimCredential = null; 827e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu /** 828e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * Set the SIM credential information. 829e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * 830e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * @param simCredential The SIM credential to set to 831e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu */ 832aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu public void setSimCredential(SimCredential simCredential) { 833aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu mSimCredential = simCredential; 834aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu } 835e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu /** 836e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * Get the SIM credential information. 837e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * 838e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * @return SIM credential information 839e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu */ 840aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu public SimCredential getSimCredential() { 841aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu return mSimCredential; 842aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu } 843e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu 844e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu /** 845e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu * CA (Certificate Authority) X509 certificate. 846e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu */ 847aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu private X509Certificate mCaCertificate = null; 848e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu /** 849e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * Set the CA (Certification Authority) certificate associated with this credential. 850e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * 851e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * @param caCertificate The CA certificate to set to 852e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu */ 853aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu public void setCaCertificate(X509Certificate caCertificate) { 854aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu mCaCertificate = caCertificate; 855aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu } 856e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu /** 857e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * Get the CA (Certification Authority) certificate associated with this credential. 858e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * 859e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * @return CA certificate associated with this credential 860e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu */ 861aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu public X509Certificate getCaCertificate() { 862aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu return mCaCertificate; 863aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu } 864e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu 865e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu /** 866e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu * Client side X509 certificate chain. 867e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu */ 868aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu private X509Certificate[] mClientCertificateChain = null; 869e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu /** 870e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * Set the client certificate chain associated with this credential. 871e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * 872e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * @param certificateChain The client certificate chain to set to 873e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu */ 874aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu public void setClientCertificateChain(X509Certificate[] certificateChain) { 875aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu mClientCertificateChain = certificateChain; 876aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu } 877e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu /** 878e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * Get the client certificate chain associated with this credential. 879e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * 880e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * @return client certificate chain associated with this credential 881e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu */ 882aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu public X509Certificate[] getClientCertificateChain() { 883aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu return mClientCertificateChain; 884aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu } 885e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu 886e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu /** 887e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu * Client side private key. 888e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu */ 889aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu private PrivateKey mClientPrivateKey = null; 890e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu /** 891e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * Set the client private key associated with this credential. 892e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * 893e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * @param clientPrivateKey the client private key to set to 894e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu */ 895aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu public void setClientPrivateKey(PrivateKey clientPrivateKey) { 896aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu mClientPrivateKey = clientPrivateKey; 897aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu } 898e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu /** 899e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * Get the client private key associated with this credential. 900e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * 901e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu * @return client private key associated with this credential. 902e5850517c493b24982cff8c32c7fb32a8203f5b6Peter Qiu */ 903aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu public PrivateKey getClientPrivateKey() { 904aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu return mClientPrivateKey; 905aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu } 906e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu 907a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu /** 908a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu * Constructor for creating Credential with default values. 909a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu */ 910a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu public Credential() {} 911a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu 912a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu /** 913a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu * Copy constructor. 914a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu * 915a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu * @param source The source to copy from 916a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu */ 917a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu public Credential(Credential source) { 918a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu if (source != null) { 919967501ec982f14fec6a160c03e34cd2d296d7128Peter Qiu mCreationTimeInMillis = source.mCreationTimeInMillis; 920967501ec982f14fec6a160c03e34cd2d296d7128Peter Qiu mExpirationTimeInMillis = source.mExpirationTimeInMillis; 921aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu mRealm = source.mRealm; 922da8a67e8a606ebd49a724a18d3581b62121b532cPeter Qiu mCheckAaaServerCertStatus = source.mCheckAaaServerCertStatus; 923aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu if (source.mUserCredential != null) { 924aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu mUserCredential = new UserCredential(source.mUserCredential); 925a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu } 926aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu if (source.mCertCredential != null) { 927aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu mCertCredential = new CertificateCredential(source.mCertCredential); 928a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu } 929aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu if (source.mSimCredential != null) { 930aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu mSimCredential = new SimCredential(source.mSimCredential); 931a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu } 932aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu if (source.mClientCertificateChain != null) { 933aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu mClientCertificateChain = Arrays.copyOf(source.mClientCertificateChain, 934aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu source.mClientCertificateChain.length); 935a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu } 936aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu mCaCertificate = source.mCaCertificate; 937aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu mClientPrivateKey = source.mClientPrivateKey; 938a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu } 939a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu } 940a32e50986ef767f50e68083a8ee345bab3ce1ccaPeter Qiu 941e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu @Override 942e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu public int describeContents() { 943e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu return 0; 944e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu } 945e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu 946e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu @Override 947e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu public void writeToParcel(Parcel dest, int flags) { 948967501ec982f14fec6a160c03e34cd2d296d7128Peter Qiu dest.writeLong(mCreationTimeInMillis); 949967501ec982f14fec6a160c03e34cd2d296d7128Peter Qiu dest.writeLong(mExpirationTimeInMillis); 950aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu dest.writeString(mRealm); 951da8a67e8a606ebd49a724a18d3581b62121b532cPeter Qiu dest.writeInt(mCheckAaaServerCertStatus ? 1 : 0); 952aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu dest.writeParcelable(mUserCredential, flags); 953aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu dest.writeParcelable(mCertCredential, flags); 954aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu dest.writeParcelable(mSimCredential, flags); 955aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu ParcelUtil.writeCertificate(dest, mCaCertificate); 956aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu ParcelUtil.writeCertificates(dest, mClientCertificateChain); 957aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu ParcelUtil.writePrivateKey(dest, mClientPrivateKey); 958e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu } 959e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu 960e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu @Override 961e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu public boolean equals(Object thatObject) { 962e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu if (this == thatObject) { 963e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu return true; 964e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu } 965e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu if (!(thatObject instanceof Credential)) { 966e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu return false; 967e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu } 968e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu 969e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu Credential that = (Credential) thatObject; 970aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu return TextUtils.equals(mRealm, that.mRealm) 971967501ec982f14fec6a160c03e34cd2d296d7128Peter Qiu && mCreationTimeInMillis == that.mCreationTimeInMillis 972967501ec982f14fec6a160c03e34cd2d296d7128Peter Qiu && mExpirationTimeInMillis == that.mExpirationTimeInMillis 973da8a67e8a606ebd49a724a18d3581b62121b532cPeter Qiu && mCheckAaaServerCertStatus == that.mCheckAaaServerCertStatus 974aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu && (mUserCredential == null ? that.mUserCredential == null 975aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu : mUserCredential.equals(that.mUserCredential)) 976aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu && (mCertCredential == null ? that.mCertCredential == null 977aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu : mCertCredential.equals(that.mCertCredential)) 978aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu && (mSimCredential == null ? that.mSimCredential == null 979aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu : mSimCredential.equals(that.mSimCredential)) 980aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu && isX509CertificateEquals(mCaCertificate, that.mCaCertificate) 981aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu && isX509CertificatesEquals(mClientCertificateChain, that.mClientCertificateChain) 982aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu && isPrivateKeyEquals(mClientPrivateKey, that.mClientPrivateKey); 983e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu } 984e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu 985ddafc73496e3bab135ac7249bfb3cf4d871e5cf2Peter Qiu @Override 986ddafc73496e3bab135ac7249bfb3cf4d871e5cf2Peter Qiu public int hashCode() { 987967501ec982f14fec6a160c03e34cd2d296d7128Peter Qiu return Objects.hash(mRealm, mCreationTimeInMillis, mExpirationTimeInMillis, 988da8a67e8a606ebd49a724a18d3581b62121b532cPeter Qiu mCheckAaaServerCertStatus, mUserCredential, mCertCredential, mSimCredential, 989ddafc73496e3bab135ac7249bfb3cf4d871e5cf2Peter Qiu mCaCertificate, mClientCertificateChain, mClientPrivateKey); 990ddafc73496e3bab135ac7249bfb3cf4d871e5cf2Peter Qiu } 991ddafc73496e3bab135ac7249bfb3cf4d871e5cf2Peter Qiu 99289537734e19fac6947ee14a1b912c5c135042837Peter Qiu @Override 99389537734e19fac6947ee14a1b912c5c135042837Peter Qiu public String toString() { 99489537734e19fac6947ee14a1b912c5c135042837Peter Qiu StringBuilder builder = new StringBuilder(); 99589537734e19fac6947ee14a1b912c5c135042837Peter Qiu builder.append("Realm: ").append(mRealm).append("\n"); 996967501ec982f14fec6a160c03e34cd2d296d7128Peter Qiu builder.append("CreationTime: ").append(mCreationTimeInMillis != Long.MIN_VALUE 997967501ec982f14fec6a160c03e34cd2d296d7128Peter Qiu ? new Date(mCreationTimeInMillis) : "Not specified").append("\n"); 998967501ec982f14fec6a160c03e34cd2d296d7128Peter Qiu builder.append("ExpirationTime: ").append(mExpirationTimeInMillis != Long.MIN_VALUE 999967501ec982f14fec6a160c03e34cd2d296d7128Peter Qiu ? new Date(mExpirationTimeInMillis) : "Not specified").append("\n"); 100089537734e19fac6947ee14a1b912c5c135042837Peter Qiu builder.append("CheckAAAServerStatus: ").append(mCheckAaaServerCertStatus).append("\n"); 100189537734e19fac6947ee14a1b912c5c135042837Peter Qiu if (mUserCredential != null) { 100289537734e19fac6947ee14a1b912c5c135042837Peter Qiu builder.append("UserCredential Begin ---\n"); 100389537734e19fac6947ee14a1b912c5c135042837Peter Qiu builder.append(mUserCredential); 100489537734e19fac6947ee14a1b912c5c135042837Peter Qiu builder.append("UserCredential End ---\n"); 100589537734e19fac6947ee14a1b912c5c135042837Peter Qiu } 100689537734e19fac6947ee14a1b912c5c135042837Peter Qiu if (mCertCredential != null) { 100789537734e19fac6947ee14a1b912c5c135042837Peter Qiu builder.append("CertificateCredential Begin ---\n"); 100889537734e19fac6947ee14a1b912c5c135042837Peter Qiu builder.append(mCertCredential); 100989537734e19fac6947ee14a1b912c5c135042837Peter Qiu builder.append("CertificateCredential End ---\n"); 101089537734e19fac6947ee14a1b912c5c135042837Peter Qiu } 101189537734e19fac6947ee14a1b912c5c135042837Peter Qiu if (mSimCredential != null) { 101289537734e19fac6947ee14a1b912c5c135042837Peter Qiu builder.append("SIMCredential Begin ---\n"); 101389537734e19fac6947ee14a1b912c5c135042837Peter Qiu builder.append(mSimCredential); 101489537734e19fac6947ee14a1b912c5c135042837Peter Qiu builder.append("SIMCredential End ---\n"); 101589537734e19fac6947ee14a1b912c5c135042837Peter Qiu } 101689537734e19fac6947ee14a1b912c5c135042837Peter Qiu return builder.toString(); 101789537734e19fac6947ee14a1b912c5c135042837Peter Qiu } 101889537734e19fac6947ee14a1b912c5c135042837Peter Qiu 1019a25d717de870895be52e81b585a8484fff0c6109Peter Qiu /** 1020a25d717de870895be52e81b585a8484fff0c6109Peter Qiu * Validate the configuration data. 1021a25d717de870895be52e81b585a8484fff0c6109Peter Qiu * 1022a25d717de870895be52e81b585a8484fff0c6109Peter Qiu * @return true on success or false on failure 1023b5ca6f36b54023f6336740cf3bff79c08ecb6609Peter Qiu * @hide 1024a25d717de870895be52e81b585a8484fff0c6109Peter Qiu */ 1025a25d717de870895be52e81b585a8484fff0c6109Peter Qiu public boolean validate() { 1026aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu if (TextUtils.isEmpty(mRealm)) { 1027a25d717de870895be52e81b585a8484fff0c6109Peter Qiu Log.d(TAG, "Missing realm"); 1028a25d717de870895be52e81b585a8484fff0c6109Peter Qiu return false; 1029a25d717de870895be52e81b585a8484fff0c6109Peter Qiu } 1030aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu if (mRealm.getBytes(StandardCharsets.UTF_8).length > MAX_REALM_BYTES) { 1031444dc5d099788e5aa0fd0e664fd952fbb07a69d4Peter Qiu Log.d(TAG, "realm exceeding maximum length: " 1032aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu + mRealm.getBytes(StandardCharsets.UTF_8).length); 1033a25d717de870895be52e81b585a8484fff0c6109Peter Qiu return false; 1034a25d717de870895be52e81b585a8484fff0c6109Peter Qiu } 1035a25d717de870895be52e81b585a8484fff0c6109Peter Qiu 1036a25d717de870895be52e81b585a8484fff0c6109Peter Qiu // Verify the credential. 1037aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu if (mUserCredential != null) { 1038a25d717de870895be52e81b585a8484fff0c6109Peter Qiu if (!verifyUserCredential()) { 1039a25d717de870895be52e81b585a8484fff0c6109Peter Qiu return false; 1040a25d717de870895be52e81b585a8484fff0c6109Peter Qiu } 1041aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu } else if (mCertCredential != null) { 1042a25d717de870895be52e81b585a8484fff0c6109Peter Qiu if (!verifyCertCredential()) { 1043a25d717de870895be52e81b585a8484fff0c6109Peter Qiu return false; 1044a25d717de870895be52e81b585a8484fff0c6109Peter Qiu } 1045aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu } else if (mSimCredential != null) { 1046a25d717de870895be52e81b585a8484fff0c6109Peter Qiu if (!verifySimCredential()) { 1047a25d717de870895be52e81b585a8484fff0c6109Peter Qiu return false; 1048a25d717de870895be52e81b585a8484fff0c6109Peter Qiu } 1049a25d717de870895be52e81b585a8484fff0c6109Peter Qiu } else { 1050a25d717de870895be52e81b585a8484fff0c6109Peter Qiu Log.d(TAG, "Missing required credential"); 1051a25d717de870895be52e81b585a8484fff0c6109Peter Qiu return false; 1052a25d717de870895be52e81b585a8484fff0c6109Peter Qiu } 1053a25d717de870895be52e81b585a8484fff0c6109Peter Qiu 1054a25d717de870895be52e81b585a8484fff0c6109Peter Qiu return true; 1055a25d717de870895be52e81b585a8484fff0c6109Peter Qiu } 1056a25d717de870895be52e81b585a8484fff0c6109Peter Qiu 1057e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu public static final Creator<Credential> CREATOR = 1058e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu new Creator<Credential>() { 1059e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu @Override 1060e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu public Credential createFromParcel(Parcel in) { 1061e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu Credential credential = new Credential(); 1062967501ec982f14fec6a160c03e34cd2d296d7128Peter Qiu credential.setCreationTimeInMillis(in.readLong()); 1063967501ec982f14fec6a160c03e34cd2d296d7128Peter Qiu credential.setExpirationTimeInMillis(in.readLong()); 1064aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu credential.setRealm(in.readString()); 1065da8a67e8a606ebd49a724a18d3581b62121b532cPeter Qiu credential.setCheckAaaServerCertStatus(in.readInt() != 0); 1066aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu credential.setUserCredential(in.readParcelable(null)); 1067aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu credential.setCertCredential(in.readParcelable(null)); 1068aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu credential.setSimCredential(in.readParcelable(null)); 1069aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu credential.setCaCertificate(ParcelUtil.readCertificate(in)); 1070aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu credential.setClientCertificateChain(ParcelUtil.readCertificates(in)); 1071aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu credential.setClientPrivateKey(ParcelUtil.readPrivateKey(in)); 1072e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu return credential; 1073e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu } 1074e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu 1075e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu @Override 1076e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu public Credential[] newArray(int size) { 1077e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu return new Credential[size]; 1078e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu } 1079e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu }; 1080e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu 1081a25d717de870895be52e81b585a8484fff0c6109Peter Qiu /** 1082a25d717de870895be52e81b585a8484fff0c6109Peter Qiu * Verify user credential. 1083a25d717de870895be52e81b585a8484fff0c6109Peter Qiu * 1084a25d717de870895be52e81b585a8484fff0c6109Peter Qiu * @return true if user credential is valid, false otherwise. 1085a25d717de870895be52e81b585a8484fff0c6109Peter Qiu */ 1086a25d717de870895be52e81b585a8484fff0c6109Peter Qiu private boolean verifyUserCredential() { 1087aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu if (mUserCredential == null) { 1088a25d717de870895be52e81b585a8484fff0c6109Peter Qiu Log.d(TAG, "Missing user credential"); 1089a25d717de870895be52e81b585a8484fff0c6109Peter Qiu return false; 1090a25d717de870895be52e81b585a8484fff0c6109Peter Qiu } 1091aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu if (mCertCredential != null || mSimCredential != null) { 1092a25d717de870895be52e81b585a8484fff0c6109Peter Qiu Log.d(TAG, "Contained more than one type of credential"); 1093a25d717de870895be52e81b585a8484fff0c6109Peter Qiu return false; 1094a25d717de870895be52e81b585a8484fff0c6109Peter Qiu } 1095aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu if (!mUserCredential.validate()) { 1096a25d717de870895be52e81b585a8484fff0c6109Peter Qiu return false; 1097a25d717de870895be52e81b585a8484fff0c6109Peter Qiu } 1098aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu if (mCaCertificate == null) { 1099a25d717de870895be52e81b585a8484fff0c6109Peter Qiu Log.d(TAG, "Missing CA Certificate for user credential"); 1100a25d717de870895be52e81b585a8484fff0c6109Peter Qiu return false; 1101a25d717de870895be52e81b585a8484fff0c6109Peter Qiu } 1102a25d717de870895be52e81b585a8484fff0c6109Peter Qiu return true; 1103a25d717de870895be52e81b585a8484fff0c6109Peter Qiu } 1104a25d717de870895be52e81b585a8484fff0c6109Peter Qiu 1105a25d717de870895be52e81b585a8484fff0c6109Peter Qiu /** 1106a25d717de870895be52e81b585a8484fff0c6109Peter Qiu * Verify certificate credential, which is used for EAP-TLS. This will verify 1107a25d717de870895be52e81b585a8484fff0c6109Peter Qiu * that the necessary client key and certificates are provided. 1108a25d717de870895be52e81b585a8484fff0c6109Peter Qiu * 1109a25d717de870895be52e81b585a8484fff0c6109Peter Qiu * @return true if certificate credential is valid, false otherwise. 1110a25d717de870895be52e81b585a8484fff0c6109Peter Qiu */ 1111a25d717de870895be52e81b585a8484fff0c6109Peter Qiu private boolean verifyCertCredential() { 1112aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu if (mCertCredential == null) { 1113a25d717de870895be52e81b585a8484fff0c6109Peter Qiu Log.d(TAG, "Missing certificate credential"); 1114a25d717de870895be52e81b585a8484fff0c6109Peter Qiu return false; 1115a25d717de870895be52e81b585a8484fff0c6109Peter Qiu } 1116aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu if (mUserCredential != null || mSimCredential != null) { 1117a25d717de870895be52e81b585a8484fff0c6109Peter Qiu Log.d(TAG, "Contained more than one type of credential"); 1118a25d717de870895be52e81b585a8484fff0c6109Peter Qiu return false; 1119a25d717de870895be52e81b585a8484fff0c6109Peter Qiu } 1120a25d717de870895be52e81b585a8484fff0c6109Peter Qiu 1121aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu if (!mCertCredential.validate()) { 1122a25d717de870895be52e81b585a8484fff0c6109Peter Qiu return false; 1123a25d717de870895be52e81b585a8484fff0c6109Peter Qiu } 1124a25d717de870895be52e81b585a8484fff0c6109Peter Qiu 1125a25d717de870895be52e81b585a8484fff0c6109Peter Qiu // Verify required key and certificates for certificate credential. 1126aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu if (mCaCertificate == null) { 1127a25d717de870895be52e81b585a8484fff0c6109Peter Qiu Log.d(TAG, "Missing CA Certificate for certificate credential"); 1128a25d717de870895be52e81b585a8484fff0c6109Peter Qiu return false; 1129a25d717de870895be52e81b585a8484fff0c6109Peter Qiu } 1130aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu if (mClientPrivateKey == null) { 1131a25d717de870895be52e81b585a8484fff0c6109Peter Qiu Log.d(TAG, "Missing client private key for certificate credential"); 1132a25d717de870895be52e81b585a8484fff0c6109Peter Qiu return false; 1133a25d717de870895be52e81b585a8484fff0c6109Peter Qiu } 1134a25d717de870895be52e81b585a8484fff0c6109Peter Qiu try { 1135a25d717de870895be52e81b585a8484fff0c6109Peter Qiu // Verify SHA-256 fingerprint for client certificate. 1136aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu if (!verifySha256Fingerprint(mClientCertificateChain, 1137aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu mCertCredential.getCertSha256Fingerprint())) { 1138a25d717de870895be52e81b585a8484fff0c6109Peter Qiu Log.d(TAG, "SHA-256 fingerprint mismatch"); 1139a25d717de870895be52e81b585a8484fff0c6109Peter Qiu return false; 1140a25d717de870895be52e81b585a8484fff0c6109Peter Qiu } 1141a25d717de870895be52e81b585a8484fff0c6109Peter Qiu } catch (NoSuchAlgorithmException | CertificateEncodingException e) { 1142a25d717de870895be52e81b585a8484fff0c6109Peter Qiu Log.d(TAG, "Failed to verify SHA-256 fingerprint: " + e.getMessage()); 1143a25d717de870895be52e81b585a8484fff0c6109Peter Qiu return false; 1144a25d717de870895be52e81b585a8484fff0c6109Peter Qiu } 1145a25d717de870895be52e81b585a8484fff0c6109Peter Qiu 1146a25d717de870895be52e81b585a8484fff0c6109Peter Qiu return true; 1147a25d717de870895be52e81b585a8484fff0c6109Peter Qiu } 1148a25d717de870895be52e81b585a8484fff0c6109Peter Qiu 1149a25d717de870895be52e81b585a8484fff0c6109Peter Qiu /** 1150a25d717de870895be52e81b585a8484fff0c6109Peter Qiu * Verify SIM credential. 1151a25d717de870895be52e81b585a8484fff0c6109Peter Qiu * 1152a25d717de870895be52e81b585a8484fff0c6109Peter Qiu * @return true if SIM credential is valid, false otherwise. 1153a25d717de870895be52e81b585a8484fff0c6109Peter Qiu */ 1154a25d717de870895be52e81b585a8484fff0c6109Peter Qiu private boolean verifySimCredential() { 1155aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu if (mSimCredential == null) { 1156a25d717de870895be52e81b585a8484fff0c6109Peter Qiu Log.d(TAG, "Missing SIM credential"); 1157a25d717de870895be52e81b585a8484fff0c6109Peter Qiu return false; 1158a25d717de870895be52e81b585a8484fff0c6109Peter Qiu } 1159aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu if (mUserCredential != null || mCertCredential != null) { 1160a25d717de870895be52e81b585a8484fff0c6109Peter Qiu Log.d(TAG, "Contained more than one type of credential"); 1161a25d717de870895be52e81b585a8484fff0c6109Peter Qiu return false; 1162a25d717de870895be52e81b585a8484fff0c6109Peter Qiu } 1163aef5b6095f58028d51e7007e7daebeac4bb2af72Peter Qiu return mSimCredential.validate(); 1164a25d717de870895be52e81b585a8484fff0c6109Peter Qiu } 1165a25d717de870895be52e81b585a8484fff0c6109Peter Qiu 1166e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu private static boolean isPrivateKeyEquals(PrivateKey key1, PrivateKey key2) { 1167e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu if (key1 == null && key2 == null) { 1168e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu return true; 1169e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu } 1170e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu 1171e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu /* Return false if only one of them is null */ 1172e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu if (key1 == null || key2 == null) { 1173e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu return false; 1174e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu } 1175e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu 1176e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu return TextUtils.equals(key1.getAlgorithm(), key2.getAlgorithm()) && 1177e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu Arrays.equals(key1.getEncoded(), key2.getEncoded()); 1178e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu } 1179e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu 1180e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu private static boolean isX509CertificateEquals(X509Certificate cert1, X509Certificate cert2) { 1181e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu if (cert1 == null && cert2 == null) { 1182e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu return true; 1183e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu } 1184e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu 1185e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu /* Return false if only one of them is null */ 1186e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu if (cert1 == null || cert2 == null) { 1187e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu return false; 1188e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu } 1189e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu 1190e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu boolean result = false; 1191e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu try { 1192e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu result = Arrays.equals(cert1.getEncoded(), cert2.getEncoded()); 1193e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu } catch (CertificateEncodingException e) { 1194e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu /* empty, return false. */ 1195e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu } 1196e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu return result; 1197e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu } 1198e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu 1199e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu private static boolean isX509CertificatesEquals(X509Certificate[] certs1, 1200e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu X509Certificate[] certs2) { 1201e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu if (certs1 == null && certs2 == null) { 1202e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu return true; 1203e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu } 1204e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu 1205e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu /* Return false if only one of them is null */ 1206e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu if (certs1 == null || certs2 == null) { 1207e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu return false; 1208e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu } 1209e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu 1210e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu if (certs1.length != certs2.length) { 1211e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu return false; 1212e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu } 1213e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu 1214e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu for (int i = 0; i < certs1.length; i++) { 1215e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu if (!isX509CertificateEquals(certs1[i], certs2[i])) { 1216e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu return false; 1217e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu } 1218e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu } 1219e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu 1220e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu return true; 1221e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu } 1222a25d717de870895be52e81b585a8484fff0c6109Peter Qiu 1223a25d717de870895be52e81b585a8484fff0c6109Peter Qiu /** 1224a25d717de870895be52e81b585a8484fff0c6109Peter Qiu * Verify that the digest for a certificate in the certificate chain matches expected 1225a25d717de870895be52e81b585a8484fff0c6109Peter Qiu * fingerprint. The certificate that matches the fingerprint is the client certificate. 1226a25d717de870895be52e81b585a8484fff0c6109Peter Qiu * 1227a25d717de870895be52e81b585a8484fff0c6109Peter Qiu * @param certChain Chain of certificates 1228a25d717de870895be52e81b585a8484fff0c6109Peter Qiu * @param expectedFingerprint The expected SHA-256 digest of the client certificate 1229a25d717de870895be52e81b585a8484fff0c6109Peter Qiu * @return true if the certificate chain contains a matching certificate, false otherwise 1230a25d717de870895be52e81b585a8484fff0c6109Peter Qiu * @throws NoSuchAlgorithmException 1231a25d717de870895be52e81b585a8484fff0c6109Peter Qiu * @throws CertificateEncodingException 1232a25d717de870895be52e81b585a8484fff0c6109Peter Qiu */ 1233a25d717de870895be52e81b585a8484fff0c6109Peter Qiu private static boolean verifySha256Fingerprint(X509Certificate[] certChain, 1234a25d717de870895be52e81b585a8484fff0c6109Peter Qiu byte[] expectedFingerprint) 1235a25d717de870895be52e81b585a8484fff0c6109Peter Qiu throws NoSuchAlgorithmException, CertificateEncodingException { 1236a25d717de870895be52e81b585a8484fff0c6109Peter Qiu if (certChain == null) { 1237a25d717de870895be52e81b585a8484fff0c6109Peter Qiu return false; 1238a25d717de870895be52e81b585a8484fff0c6109Peter Qiu } 1239a25d717de870895be52e81b585a8484fff0c6109Peter Qiu MessageDigest digester = MessageDigest.getInstance("SHA-256"); 1240a25d717de870895be52e81b585a8484fff0c6109Peter Qiu for (X509Certificate certificate : certChain) { 1241a25d717de870895be52e81b585a8484fff0c6109Peter Qiu digester.reset(); 1242a25d717de870895be52e81b585a8484fff0c6109Peter Qiu byte[] fingerprint = digester.digest(certificate.getEncoded()); 1243a25d717de870895be52e81b585a8484fff0c6109Peter Qiu if (Arrays.equals(expectedFingerprint, fingerprint)) { 1244a25d717de870895be52e81b585a8484fff0c6109Peter Qiu return true; 1245a25d717de870895be52e81b585a8484fff0c6109Peter Qiu } 1246a25d717de870895be52e81b585a8484fff0c6109Peter Qiu } 1247a25d717de870895be52e81b585a8484fff0c6109Peter Qiu return false; 1248a25d717de870895be52e81b585a8484fff0c6109Peter Qiu } 1249e557c35d95a8d05c58a592d4c34db69a1dd2c1a7Peter Qiu} 1250