1/*
2 * Copyright (C) 2015 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.security.keymaster;
18
19import android.os.Parcel;
20import android.os.Parcelable;
21
22import java.math.BigInteger;
23import java.util.ArrayList;
24import java.util.Date;
25import java.util.List;
26
27/**
28 * @hide
29 */
30public class KeyCharacteristics implements Parcelable {
31    public KeymasterArguments swEnforced;
32    public KeymasterArguments hwEnforced;
33
34    public static final Parcelable.Creator<KeyCharacteristics> CREATOR =
35            new Parcelable.Creator<KeyCharacteristics>() {
36                @Override
37                public KeyCharacteristics createFromParcel(Parcel in) {
38                    return new KeyCharacteristics(in);
39                }
40
41                @Override
42                public KeyCharacteristics[] newArray(int length) {
43                    return new KeyCharacteristics[length];
44                }
45            };
46
47    public KeyCharacteristics() {}
48
49    protected KeyCharacteristics(Parcel in) {
50        readFromParcel(in);
51    }
52
53    @Override
54    public int describeContents() {
55        return 0;
56    }
57
58    @Override
59    public void writeToParcel(Parcel out, int flags) {
60        swEnforced.writeToParcel(out, flags);
61        hwEnforced.writeToParcel(out, flags);
62    }
63
64    public void readFromParcel(Parcel in) {
65        swEnforced = KeymasterArguments.CREATOR.createFromParcel(in);
66        hwEnforced = KeymasterArguments.CREATOR.createFromParcel(in);
67    }
68
69    /**
70     * Returns the value of the specified enum tag or {@code defaultValue} if the tag is not
71     * present.
72     *
73     * @throws IllegalArgumentException if {@code tag} is not an enum tag.
74     */
75    public Integer getEnum(int tag) {
76        if (hwEnforced.containsTag(tag)) {
77            return hwEnforced.getEnum(tag, -1);
78        } else if (swEnforced.containsTag(tag)) {
79            return swEnforced.getEnum(tag, -1);
80        } else {
81            return null;
82        }
83    }
84
85    /**
86     * Returns all values of the specified repeating enum tag.
87     *
88     * throws IllegalArgumentException if {@code tag} is not a repeating enum tag.
89     */
90    public List<Integer> getEnums(int tag) {
91        List<Integer> result = new ArrayList<Integer>();
92        result.addAll(hwEnforced.getEnums(tag));
93        result.addAll(swEnforced.getEnums(tag));
94        return result;
95    }
96
97    /**
98     * Returns the value of the specified unsigned 32-bit int tag or {@code defaultValue} if the tag
99     * is not present.
100     *
101     * @throws IllegalArgumentException if {@code tag} is not an unsigned 32-bit int tag.
102     */
103    public long getUnsignedInt(int tag, long defaultValue) {
104        if (hwEnforced.containsTag(tag)) {
105            return hwEnforced.getUnsignedInt(tag, defaultValue);
106        } else {
107            return swEnforced.getUnsignedInt(tag, defaultValue);
108        }
109    }
110
111    /**
112     * Returns all values of the specified repeating unsigned 64-bit long tag.
113     *
114     * @throws IllegalArgumentException if {@code tag} is not a repeating unsigned 64-bit long tag.
115     */
116    public List<BigInteger> getUnsignedLongs(int tag) {
117        List<BigInteger> result = new ArrayList<BigInteger>();
118        result.addAll(hwEnforced.getUnsignedLongs(tag));
119        result.addAll(swEnforced.getUnsignedLongs(tag));
120        return result;
121    }
122
123    /**
124     * Returns the value of the specified date tag or {@code null} if the tag is not present.
125     *
126     * @throws IllegalArgumentException if {@code tag} is not a date tag or if the tag's value
127     *         represents a time instant which is after {@code 2^63 - 1} milliseconds since Unix
128     *         epoch.
129     */
130    public Date getDate(int tag) {
131        Date result = swEnforced.getDate(tag, null);
132        if (result != null) {
133            return result;
134        }
135        return hwEnforced.getDate(tag, null);
136    }
137
138    /**
139     * Returns {@code true} if the provided boolean tag is present, {@code false} if absent.
140     *
141     * @throws IllegalArgumentException if {@code tag} is not a boolean tag.
142     */
143    public boolean getBoolean(int tag) {
144        if (hwEnforced.containsTag(tag)) {
145            return hwEnforced.getBoolean(tag);
146        } else {
147            return swEnforced.getBoolean(tag);
148        }
149    }
150}
151
152