1package com.android.hotspot2.pps;
2
3import android.text.TextUtils;
4import android.util.Base64;
5
6import com.android.anqp.eap.EAPMethod;
7import com.android.hotspot2.IMSIParameter;
8import com.android.hotspot2.Utils;
9import com.android.hotspot2.omadm.OMAException;
10
11import java.nio.charset.StandardCharsets;
12import java.util.Arrays;
13
14public class Credential {
15    public enum CertType {IEEE, x509v3}
16
17    public static final String CertTypeX509 = "x509v3";
18    public static final String CertTypeIEEE = "802.1ar";
19
20    private final long mCtime;
21    private final long mExpTime;
22    private final String mRealm;
23    private final boolean mCheckAAACert;
24
25    private final String mUserName;
26    private final String mPassword;
27    private final boolean mDisregardPassword;
28    private final boolean mMachineManaged;
29    private final String mSTokenApp;
30    private final boolean mShare;
31    private final EAPMethod mEAPMethod;
32
33    private final CertType mCertType;
34    private final byte[] mFingerPrint;
35
36    private final IMSIParameter mImsi;
37
38    public Credential(long ctime, long expTime, String realm, boolean checkAAACert,
39                      EAPMethod eapMethod, String userName, String password,
40                      boolean machineManaged, String stApp, boolean share) {
41        mCtime = ctime;
42        mExpTime = expTime;
43        mRealm = realm;
44        mCheckAAACert = checkAAACert;
45        mEAPMethod = eapMethod;
46        mUserName = userName;
47
48        if (!TextUtils.isEmpty(password)) {
49            byte[] pwOctets = Base64.decode(password, Base64.DEFAULT);
50            mPassword = new String(pwOctets, StandardCharsets.UTF_8);
51        } else {
52            mPassword = null;
53        }
54        mDisregardPassword = false;
55
56        mMachineManaged = machineManaged;
57        mSTokenApp = stApp;
58        mShare = share;
59
60        mCertType = null;
61        mFingerPrint = null;
62
63        mImsi = null;
64    }
65
66    public Credential(long ctime, long expTime, String realm, boolean checkAAACert,
67                      EAPMethod eapMethod, Credential.CertType certType, byte[] fingerPrint) {
68        mCtime = ctime;
69        mExpTime = expTime;
70        mRealm = realm;
71        mCheckAAACert = checkAAACert;
72        mEAPMethod = eapMethod;
73        mCertType = certType;
74        mFingerPrint = fingerPrint;
75
76        mUserName = null;
77        mPassword = null;
78        mDisregardPassword = false;
79        mMachineManaged = false;
80        mSTokenApp = null;
81        mShare = false;
82
83        mImsi = null;
84    }
85
86    public Credential(long ctime, long expTime, String realm, boolean checkAAACert,
87                      EAPMethod eapMethod, IMSIParameter imsi) {
88        mCtime = ctime;
89        mExpTime = expTime;
90        mRealm = realm;
91        mCheckAAACert = checkAAACert;
92        mEAPMethod = eapMethod;
93        mImsi = imsi;
94
95        mCertType = null;
96        mFingerPrint = null;
97
98        mUserName = null;
99        mPassword = null;
100        mDisregardPassword = false;
101        mMachineManaged = false;
102        mSTokenApp = null;
103        mShare = false;
104    }
105
106    public Credential(Credential other, String password) {
107        mCtime = other.mCtime;
108        mExpTime = other.mExpTime;
109        mRealm = other.mRealm;
110        mCheckAAACert = other.mCheckAAACert;
111        mUserName = other.mUserName;
112        mPassword = password;
113        mDisregardPassword = other.mDisregardPassword;
114        mMachineManaged = other.mMachineManaged;
115        mSTokenApp = other.mSTokenApp;
116        mShare = other.mShare;
117        mEAPMethod = other.mEAPMethod;
118        mCertType = other.mCertType;
119        mFingerPrint = other.mFingerPrint;
120        mImsi = other.mImsi;
121    }
122
123    public static CertType mapCertType(String certType) throws OMAException {
124        if (certType.equalsIgnoreCase(CertTypeX509)) {
125            return CertType.x509v3;
126        } else if (certType.equalsIgnoreCase(CertTypeIEEE)) {
127            return CertType.IEEE;
128        } else {
129            throw new OMAException("Invalid cert type: '" + certType + "'");
130        }
131    }
132
133    public EAPMethod getEAPMethod() {
134        return mEAPMethod;
135    }
136
137    public String getRealm() {
138        return mRealm;
139    }
140
141    public IMSIParameter getImsi() {
142        return mImsi;
143    }
144
145    public String getUserName() {
146        return mUserName;
147    }
148
149    public String getPassword() {
150        return mPassword;
151    }
152
153    public boolean hasDisregardPassword() {
154        return mDisregardPassword;
155    }
156
157    public CertType getCertType() {
158        return mCertType;
159    }
160
161    public byte[] getFingerPrint() {
162        return mFingerPrint;
163    }
164
165    public long getCtime() {
166        return mCtime;
167    }
168
169    public long getExpTime() {
170        return mExpTime;
171    }
172
173    @Override
174    public boolean equals(Object o) {
175        if (this == o) return true;
176        if (o == null || getClass() != o.getClass()) return false;
177
178        Credential that = (Credential) o;
179
180        if (mCheckAAACert != that.mCheckAAACert) return false;
181        if (mCtime != that.mCtime) return false;
182        if (mExpTime != that.mExpTime) return false;
183        if (mMachineManaged != that.mMachineManaged) return false;
184        if (mShare != that.mShare) return false;
185        if (mCertType != that.mCertType) return false;
186        if (!mEAPMethod.equals(that.mEAPMethod)) return false;
187        if (!Arrays.equals(mFingerPrint, that.mFingerPrint)) return false;
188        if (!safeEquals(mImsi, that.mImsi)) {
189            return false;
190        }
191
192        if (!mDisregardPassword && !safeEquals(mPassword, that.mPassword)) {
193            return false;
194        }
195
196        if (!mRealm.equals(that.mRealm)) return false;
197        if (!safeEquals(mSTokenApp, that.mSTokenApp)) {
198            return false;
199        }
200        if (!safeEquals(mUserName, that.mUserName)) {
201            return false;
202        }
203
204        return true;
205    }
206
207    private static boolean safeEquals(Object s1, Object s2) {
208        if (s1 == null) {
209            return s2 == null;
210        } else {
211            return s2 != null && s1.equals(s2);
212        }
213    }
214
215    @Override
216    public int hashCode() {
217        int result = (int) (mCtime ^ (mCtime >>> 32));
218        result = 31 * result + (int) (mExpTime ^ (mExpTime >>> 32));
219        result = 31 * result + mRealm.hashCode();
220        result = 31 * result + (mCheckAAACert ? 1 : 0);
221        result = 31 * result + (mUserName != null ? mUserName.hashCode() : 0);
222        result = 31 * result + (mPassword != null ? mPassword.hashCode() : 0);
223        result = 31 * result + (mMachineManaged ? 1 : 0);
224        result = 31 * result + (mSTokenApp != null ? mSTokenApp.hashCode() : 0);
225        result = 31 * result + (mShare ? 1 : 0);
226        result = 31 * result + mEAPMethod.hashCode();
227        result = 31 * result + (mCertType != null ? mCertType.hashCode() : 0);
228        result = 31 * result + (mFingerPrint != null ? Arrays.hashCode(mFingerPrint) : 0);
229        result = 31 * result + (mImsi != null ? mImsi.hashCode() : 0);
230        return result;
231    }
232
233    @Override
234    public String toString() {
235        return "Credential{" +
236                "mCtime=" + Utils.toUTCString(mCtime) +
237                ", mExpTime=" + Utils.toUTCString(mExpTime) +
238                ", mRealm='" + mRealm + '\'' +
239                ", mCheckAAACert=" + mCheckAAACert +
240                ", mUserName='" + mUserName + '\'' +
241                ", mPassword='" + mPassword + '\'' +
242                ", mDisregardPassword=" + mDisregardPassword +
243                ", mMachineManaged=" + mMachineManaged +
244                ", mSTokenApp='" + mSTokenApp + '\'' +
245                ", mShare=" + mShare +
246                ", mEAPMethod=" + mEAPMethod +
247                ", mCertType=" + mCertType +
248                ", mFingerPrint=" + Utils.toHexString(mFingerPrint) +
249                ", mImsi='" + mImsi + '\'' +
250                '}';
251    }
252}
253