1/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.net.lowpan;
18
19import android.os.Parcel;
20import android.os.Parcelable;
21import com.android.internal.util.HexDump;
22import java.util.Arrays;
23import java.util.Objects;
24
25/**
26 * Describes a credential for a LoWPAN network.
27 *
28 * @hide
29 */
30// @SystemApi
31public class LowpanCredential implements Parcelable {
32
33    public static final int UNSPECIFIED_KEY_INDEX = 0;
34
35    private byte[] mMasterKey = null;
36    private int mMasterKeyIndex = UNSPECIFIED_KEY_INDEX;
37
38    LowpanCredential() {}
39
40    private LowpanCredential(byte[] masterKey, int keyIndex) {
41        setMasterKey(masterKey, keyIndex);
42    }
43
44    private LowpanCredential(byte[] masterKey) {
45        setMasterKey(masterKey);
46    }
47
48    public static LowpanCredential createMasterKey(byte[] masterKey) {
49        return new LowpanCredential(masterKey);
50    }
51
52    public static LowpanCredential createMasterKey(byte[] masterKey, int keyIndex) {
53        return new LowpanCredential(masterKey, keyIndex);
54    }
55
56    void setMasterKey(byte[] masterKey) {
57        if (masterKey != null) {
58            masterKey = masterKey.clone();
59        }
60        mMasterKey = masterKey;
61    }
62
63    void setMasterKeyIndex(int keyIndex) {
64        mMasterKeyIndex = keyIndex;
65    }
66
67    void setMasterKey(byte[] masterKey, int keyIndex) {
68        setMasterKey(masterKey);
69        setMasterKeyIndex(keyIndex);
70    }
71
72    public byte[] getMasterKey() {
73        if (mMasterKey != null) {
74            return mMasterKey.clone();
75        }
76        return null;
77    }
78
79    public int getMasterKeyIndex() {
80        return mMasterKeyIndex;
81    }
82
83    public boolean isMasterKey() {
84        return mMasterKey != null;
85    }
86
87    public String toSensitiveString() {
88        StringBuffer sb = new StringBuffer();
89
90        sb.append("<LowpanCredential");
91
92        if (isMasterKey()) {
93            sb.append(" MasterKey:").append(HexDump.toHexString(mMasterKey));
94            if (mMasterKeyIndex != UNSPECIFIED_KEY_INDEX) {
95                sb.append(", Index:").append(mMasterKeyIndex);
96            }
97        } else {
98            sb.append(" empty");
99        }
100
101        sb.append(">");
102
103        return sb.toString();
104    }
105
106    @Override
107    public String toString() {
108        StringBuffer sb = new StringBuffer();
109
110        sb.append("<LowpanCredential");
111
112        if (isMasterKey()) {
113            // We don't print out the contents of the key here,
114            // we only do that in toSensitiveString.
115            sb.append(" MasterKey");
116            if (mMasterKeyIndex != UNSPECIFIED_KEY_INDEX) {
117                sb.append(", Index:").append(mMasterKeyIndex);
118            }
119        } else {
120            sb.append(" empty");
121        }
122
123        sb.append(">");
124
125        return sb.toString();
126    }
127
128    @Override
129    public boolean equals(Object obj) {
130        if (!(obj instanceof LowpanCredential)) {
131            return false;
132        }
133        LowpanCredential rhs = (LowpanCredential) obj;
134        return Arrays.equals(mMasterKey, rhs.mMasterKey) && mMasterKeyIndex == rhs.mMasterKeyIndex;
135    }
136
137    @Override
138    public int hashCode() {
139        return Objects.hash(Arrays.hashCode(mMasterKey), mMasterKeyIndex);
140    }
141
142    /** Implement the Parcelable interface. */
143    @Override
144    public int describeContents() {
145        return 0;
146    }
147
148    /** Implement the Parcelable interface. */
149    @Override
150    public void writeToParcel(Parcel dest, int flags) {
151        dest.writeByteArray(mMasterKey);
152        dest.writeInt(mMasterKeyIndex);
153    }
154
155    /** Implement the Parcelable interface. */
156    public static final Creator<LowpanCredential> CREATOR =
157            new Creator<LowpanCredential>() {
158
159                public LowpanCredential createFromParcel(Parcel in) {
160                    LowpanCredential credential = new LowpanCredential();
161
162                    credential.mMasterKey = in.createByteArray();
163                    credential.mMasterKeyIndex = in.readInt();
164
165                    return credential;
166                }
167
168                public LowpanCredential[] newArray(int size) {
169                    return new LowpanCredential[size];
170                }
171            };
172}
173