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