• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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;
18 
19 import android.annotation.NonNull;
20 import android.hardware.security.keymint.KeyParameter;
21 import android.os.Binder;
22 import android.os.RemoteException;
23 import android.os.ServiceSpecificException;
24 import android.os.StrictMode;
25 import android.security.keymaster.KeymasterDefs;
26 import android.system.keystore2.IKeystoreOperation;
27 import android.system.keystore2.ResponseCode;
28 import android.util.Log;
29 
30 /**
31  * @hide
32  */
33 public class KeyStoreOperation {
34     static final String TAG = "KeyStoreOperation";
35     private final IKeystoreOperation mOperation;
36     private final Long mChallenge;
37     private final KeyParameter[] mParameters;
38 
KeyStoreOperation( @onNull IKeystoreOperation operation, Long challenge, KeyParameter[] parameters )39     public KeyStoreOperation(
40             @NonNull IKeystoreOperation operation,
41             Long challenge,
42             KeyParameter[] parameters
43     ) {
44         Binder.allowBlocking(operation.asBinder());
45         this.mOperation = operation;
46         this.mChallenge = challenge;
47         this.mParameters = parameters;
48     }
49 
50     /**
51      * Gets the challenge associated with this operation.
52      * @return null if the operation does not required authorization. A 64bit operation
53      *         challenge otherwise.
54      */
getChallenge()55     public Long getChallenge() {
56         return mChallenge;
57     }
58 
59     /**
60      * Gets the parameters associated with this operation.
61      * @return
62      */
getParameters()63     public KeyParameter[] getParameters() {
64         return mParameters;
65     }
66 
handleExceptions(@onNull CheckedRemoteRequest<R> request)67     private <R> R handleExceptions(@NonNull CheckedRemoteRequest<R> request)
68             throws KeyStoreException {
69         try {
70             return request.execute();
71         } catch (ServiceSpecificException e) {
72             switch(e.errorCode) {
73                 case ResponseCode.OPERATION_BUSY: {
74                     throw new IllegalThreadStateException(
75                             "Cannot update the same operation concurrently."
76                     );
77                 }
78                 default:
79                     throw KeyStore2.getKeyStoreException(e.errorCode, e.getMessage());
80             }
81         } catch (RemoteException e) {
82             // Log exception and report invalid operation handle.
83             // This should prompt the caller drop the reference to this operation and retry.
84             Log.e(
85                     TAG,
86                     "Remote exception while advancing a KeyStoreOperation.",
87                     e
88             );
89             throw new KeyStoreException(KeymasterDefs.KM_ERROR_INVALID_OPERATION_HANDLE, "",
90                     e.getMessage());
91         }
92     }
93 
94     /**
95      * Updates the Keystore operation represented by this object with more associated data.
96      * @see IKeystoreOperation#updateAad(byte[]) for more details.
97      * @param input
98      * @throws KeyStoreException
99      */
updateAad(@onNull byte[] input)100     public void updateAad(@NonNull byte[] input) throws KeyStoreException {
101         StrictMode.noteSlowCall("updateAad");
102         handleExceptions(() -> {
103             mOperation.updateAad(input);
104             return 0;
105         });
106     }
107 
108     /**
109      * Updates the Keystore operation represented by this object.
110      * @see IKeystoreOperation#update(byte[]) for more details.
111      * @param input
112      * @return
113      * @throws KeyStoreException
114      * @hide
115      */
update(@onNull byte[] input)116     public byte[] update(@NonNull byte[] input) throws KeyStoreException {
117         StrictMode.noteSlowCall("update");
118         return handleExceptions(() -> mOperation.update(input));
119     }
120 
121     /**
122      * Finalizes the Keystore operation represented by this object.
123      * @see IKeystoreOperation#finish(byte[], byte[]) for more details.
124      * @param input
125      * @param signature
126      * @return
127      * @throws KeyStoreException
128      * @hide
129      */
finish(byte[] input, byte[] signature)130     public byte[] finish(byte[] input, byte[] signature) throws KeyStoreException {
131         StrictMode.noteSlowCall("finish");
132         return handleExceptions(() -> mOperation.finish(input, signature));
133     }
134 
135     /**
136      * Aborts the Keystore operation represented by this object.
137      * @see IKeystoreOperation#abort() for more details.
138      * @throws KeyStoreException
139      * @hide
140      */
abort()141     public void abort() throws KeyStoreException {
142         StrictMode.noteSlowCall("abort");
143         handleExceptions(() -> {
144             mOperation.abort();
145             return 0;
146         });
147     }
148 }
149