1/*
2 * Copyright (C) 2013 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 com.android.server.pm;
18
19import android.util.ArrayMap;
20
21import com.android.internal.util.ArrayUtils;
22
23public class PackageKeySetData {
24
25    static final long KEYSET_UNASSIGNED = -1;
26
27    /* KeySet containing all signing keys - superset of the others */
28    private long mProperSigningKeySet;
29
30    private long[] mSigningKeySets;
31
32    private long[] mUpgradeKeySets;
33
34    private long[] mDefinedKeySets;
35
36    private final ArrayMap<String, Long> mKeySetAliases = new ArrayMap<String, Long>();
37
38    PackageKeySetData() {
39        mProperSigningKeySet = KEYSET_UNASSIGNED;
40    }
41
42    PackageKeySetData(PackageKeySetData original) {
43        mProperSigningKeySet = original.mProperSigningKeySet;
44        mSigningKeySets = ArrayUtils.cloneOrNull(original.mSigningKeySets);
45        mUpgradeKeySets = ArrayUtils.cloneOrNull(original.mUpgradeKeySets);
46        mDefinedKeySets = ArrayUtils.cloneOrNull(original.mDefinedKeySets);
47        mKeySetAliases.putAll(original.mKeySetAliases);
48    }
49
50    protected void setProperSigningKeySet(long ks) {
51        if (ks == mProperSigningKeySet) {
52
53            /* nothing to change */
54            return;
55        }
56
57        /* otherwise, our current signing keysets are likely invalid */
58        removeAllSigningKeySets();
59        mProperSigningKeySet = ks;
60        addSigningKeySet(ks);
61        return;
62    }
63
64    protected long getProperSigningKeySet() {
65        return mProperSigningKeySet;
66    }
67
68    protected void addSigningKeySet(long ks) {
69        mSigningKeySets = ArrayUtils.appendLong(mSigningKeySets, ks);
70    }
71
72    protected void removeSigningKeySet(long ks) {
73        mSigningKeySets = ArrayUtils.removeLong(mSigningKeySets, ks);
74    }
75
76    protected void addUpgradeKeySet(String alias) {
77
78        /* must have previously been defined */
79        Long ks = mKeySetAliases.get(alias);
80        if (ks != null) {
81            mUpgradeKeySets = ArrayUtils.appendLong(mUpgradeKeySets, ks);
82        } else {
83            throw new IllegalArgumentException("Upgrade keyset alias " + alias
84                    + "does not refer to a defined keyset alias!");
85        }
86    }
87
88    /*
89     * Used only when restoring keyset data from persistent storage.  Must
90     * correspond to a defined-keyset.
91     */
92    protected void addUpgradeKeySetById(long ks) {
93        mSigningKeySets = ArrayUtils.appendLong(mSigningKeySets, ks);
94    }
95
96    protected void addDefinedKeySet(long ks, String alias) {
97        mDefinedKeySets = ArrayUtils.appendLong(mDefinedKeySets, ks);
98        mKeySetAliases.put(alias, ks);
99    }
100
101    protected void removeAllSigningKeySets() {
102        mProperSigningKeySet = KEYSET_UNASSIGNED;
103        mSigningKeySets = null;
104        return;
105    }
106
107    protected void removeAllUpgradeKeySets() {
108        mUpgradeKeySets = null;
109        return;
110    }
111
112    protected void removeAllDefinedKeySets() {
113        mDefinedKeySets = null;
114        mKeySetAliases.clear();
115        return;
116    }
117
118    protected boolean packageIsSignedBy(long ks) {
119        return ArrayUtils.contains(mSigningKeySets, ks);
120    }
121
122    protected long[] getSigningKeySets() {
123        return mSigningKeySets;
124    }
125
126    protected long[] getUpgradeKeySets() {
127        return mUpgradeKeySets;
128    }
129
130    protected long[] getDefinedKeySets() {
131        return mDefinedKeySets;
132    }
133
134    protected ArrayMap<String, Long> getAliases() {
135        return mKeySetAliases;
136    }
137
138    protected boolean isUsingDefinedKeySets() {
139
140        /* should never be the case that mDefinedKeySets.length == 0 */
141        return (mDefinedKeySets != null && mDefinedKeySets.length > 0);
142    }
143
144    protected boolean isUsingUpgradeKeySets() {
145
146        /* should never be the case that mUpgradeKeySets.length == 0 */
147        return (mUpgradeKeySets != null && mUpgradeKeySets.length > 0);
148    }
149}
150