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 
17 package android.security.keystore2;
18 
19 import android.annotation.NonNull;
20 import android.security.KeyStoreSecurityLevel;
21 import android.system.keystore2.Authorization;
22 import android.system.keystore2.Domain;
23 import android.system.keystore2.KeyDescriptor;
24 
25 import com.android.internal.annotations.VisibleForTesting;
26 
27 import java.security.Key;
28 
29 /**
30  * {@link Key} backed by Android Keystore.
31  *
32  * @hide
33  */
34 public class AndroidKeyStoreKey implements Key {
35     // This is the original KeyDescriptor by which the key was loaded from
36     // with alias and domain.
37     private final KeyDescriptor mDescriptor;
38     // The key id can be used make certain manipulations to the keystore database
39     // assuring that the manipulation is made to the exact key that was loaded
40     // from the database. Alias based manipulations can not assure this, because
41     // aliases can be rebound to other keys at any time.
42     private final long mKeyId;
43     private final Authorization[] mAuthorizations;
44     // TODO extract algorithm string from metadata.
45     private final String mAlgorithm;
46 
47     // This is the security level interface, that this key is associated with.
48     // We do not include this member in comparisons.
49     private final KeyStoreSecurityLevel mSecurityLevel;
50 
51     /**
52      * @hide
53      */
54     @VisibleForTesting
AndroidKeyStoreKey(@onNull KeyDescriptor descriptor, long keyId, @NonNull Authorization[] authorizations, @NonNull String algorithm, @NonNull KeyStoreSecurityLevel securityLevel)55     public AndroidKeyStoreKey(@NonNull KeyDescriptor descriptor,
56             long keyId,
57             @NonNull Authorization[] authorizations,
58             @NonNull String algorithm,
59             @NonNull KeyStoreSecurityLevel securityLevel) {
60         mDescriptor = descriptor;
61         mKeyId = keyId;
62         mAuthorizations = authorizations;
63         mAlgorithm = algorithm;
64         mSecurityLevel = securityLevel;
65     }
66 
getUserKeyDescriptor()67     KeyDescriptor getUserKeyDescriptor() {
68         return mDescriptor;
69     }
70 
getKeyIdDescriptor()71     KeyDescriptor getKeyIdDescriptor() {
72         KeyDescriptor descriptor = new KeyDescriptor();
73         descriptor.nspace = mKeyId;
74         descriptor.domain = Domain.KEY_ID;
75         descriptor.alias = null;
76         descriptor.blob = null;
77         return descriptor;
78     }
79 
getAuthorizations()80     Authorization[] getAuthorizations() {
81         return mAuthorizations;
82     }
83 
getSecurityLevel()84     KeyStoreSecurityLevel getSecurityLevel() {
85         return mSecurityLevel;
86     }
87 
88 
89     @Override
getAlgorithm()90     public String getAlgorithm() {
91         return mAlgorithm;
92     }
93 
94     @Override
getFormat()95     public String getFormat() {
96         // This key does not export its key material
97         return null;
98     }
99 
100     @Override
getEncoded()101     public byte[] getEncoded() {
102         // This key does not export its key material
103         return null;
104     }
105 
106     @Override
hashCode()107     public int hashCode() {
108         final int prime = 31;
109         int result = 1;
110 
111         result = prime * result + getClass().hashCode();
112         result = prime * result + (int) (mKeyId >>> 32);
113         result = prime * result + (int) (mKeyId & 0xffffffff);
114         return result;
115     }
116 
117     @Override
equals(Object obj)118     public boolean equals(Object obj) {
119         if (this == obj) {
120             return true;
121         }
122         if (obj == null) {
123             return false;
124         }
125         if (getClass() != obj.getClass()) {
126             return false;
127         }
128         AndroidKeyStoreKey other = (AndroidKeyStoreKey) obj;
129         return mKeyId == other.mKeyId;
130     }
131 }
132