1 /*
2  * Copyright 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 #define LOG_TAG "GateKeeperService"
18 #include <utils/Log.h>
19 
20 #include "IGateKeeperService.h"
21 
22 namespace android {
23 
24 const android::String16 IGateKeeperService::descriptor("android.service.gatekeeper.IGateKeeperService");
getInterfaceDescriptor() const25 const android::String16& IGateKeeperService::getInterfaceDescriptor() const {
26     return IGateKeeperService::descriptor;
27 }
28 
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)29 status_t BnGateKeeperService::onTransact(
30     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
31     switch(code) {
32         case ENROLL: {
33             CHECK_INTERFACE(IGateKeeperService, data, reply);
34             uint32_t uid = data.readInt32();
35 
36             ssize_t currentPasswordHandleSize = data.readInt32();
37             const uint8_t *currentPasswordHandle =
38                     static_cast<const uint8_t *>(data.readInplace(currentPasswordHandleSize));
39             if (!currentPasswordHandle) currentPasswordHandleSize = 0;
40 
41             ssize_t currentPasswordSize = data.readInt32();
42             const uint8_t *currentPassword =
43                     static_cast<const uint8_t *>(data.readInplace(currentPasswordSize));
44             if (!currentPassword) currentPasswordSize = 0;
45 
46             ssize_t desiredPasswordSize = data.readInt32();
47             const uint8_t *desiredPassword =
48                     static_cast<const uint8_t *>(data.readInplace(desiredPasswordSize));
49             if (!desiredPassword) desiredPasswordSize = 0;
50 
51             uint8_t *out = NULL;
52             uint32_t outSize = 0;
53             int ret = enroll(uid, currentPasswordHandle, currentPasswordHandleSize,
54                     currentPassword, currentPasswordSize, desiredPassword,
55                     desiredPasswordSize, &out, &outSize);
56 
57             reply->writeNoException();
58             reply->writeInt32(1);
59             if (ret == 0 && outSize > 0 && out != NULL) {
60                 reply->writeInt32(GATEKEEPER_RESPONSE_OK);
61                 reply->writeInt32(0);
62                 reply->writeInt32(outSize);
63                 reply->writeInt32(outSize);
64                 void *buf = reply->writeInplace(outSize);
65                 memcpy(buf, out, outSize);
66                 delete[] out;
67             } else if (ret > 0) {
68                 reply->writeInt32(GATEKEEPER_RESPONSE_RETRY);
69                 reply->writeInt32(ret);
70             } else {
71                 reply->writeInt32(GATEKEEPER_RESPONSE_ERROR);
72             }
73             return NO_ERROR;
74         }
75         case VERIFY: {
76             CHECK_INTERFACE(IGateKeeperService, data, reply);
77             uint32_t uid = data.readInt32();
78             ssize_t currentPasswordHandleSize = data.readInt32();
79             const uint8_t *currentPasswordHandle =
80                     static_cast<const uint8_t *>(data.readInplace(currentPasswordHandleSize));
81             if (!currentPasswordHandle) currentPasswordHandleSize = 0;
82 
83             ssize_t currentPasswordSize = data.readInt32();
84             const uint8_t *currentPassword =
85                 static_cast<const uint8_t *>(data.readInplace(currentPasswordSize));
86             if (!currentPassword) currentPasswordSize = 0;
87 
88             bool request_reenroll = false;
89             int ret = verify(uid, (uint8_t *) currentPasswordHandle,
90                     currentPasswordHandleSize, (uint8_t *) currentPassword, currentPasswordSize,
91                     &request_reenroll);
92 
93             reply->writeNoException();
94             reply->writeInt32(1);
95             if (ret == 0) {
96                 reply->writeInt32(GATEKEEPER_RESPONSE_OK);
97                 reply->writeInt32(request_reenroll ? 1 : 0);
98                 reply->writeInt32(0); // no payload returned from this call
99             } else if (ret > 0) {
100                 reply->writeInt32(GATEKEEPER_RESPONSE_RETRY);
101                 reply->writeInt32(ret);
102             } else {
103                 reply->writeInt32(GATEKEEPER_RESPONSE_ERROR);
104             }
105             return NO_ERROR;
106         }
107         case VERIFY_CHALLENGE: {
108             CHECK_INTERFACE(IGateKeeperService, data, reply);
109             uint32_t uid = data.readInt32();
110             uint64_t challenge = data.readInt64();
111             ssize_t currentPasswordHandleSize = data.readInt32();
112             const uint8_t *currentPasswordHandle =
113                     static_cast<const uint8_t *>(data.readInplace(currentPasswordHandleSize));
114             if (!currentPasswordHandle) currentPasswordHandleSize = 0;
115 
116             ssize_t currentPasswordSize = data.readInt32();
117             const uint8_t *currentPassword =
118                 static_cast<const uint8_t *>(data.readInplace(currentPasswordSize));
119             if (!currentPassword) currentPasswordSize = 0;
120 
121 
122             uint8_t *out = NULL;
123             uint32_t outSize = 0;
124             bool request_reenroll = false;
125             int ret = verifyChallenge(uid, challenge, (uint8_t *) currentPasswordHandle,
126                     currentPasswordHandleSize, (uint8_t *) currentPassword, currentPasswordSize,
127                     &out, &outSize, &request_reenroll);
128             reply->writeNoException();
129             reply->writeInt32(1);
130             if (ret == 0 && outSize > 0 && out != NULL) {
131                 reply->writeInt32(GATEKEEPER_RESPONSE_OK);
132                 reply->writeInt32(request_reenroll ? 1 : 0);
133                 reply->writeInt32(outSize);
134                 reply->writeInt32(outSize);
135                 void *buf = reply->writeInplace(outSize);
136                 memcpy(buf, out, outSize);
137                 delete[] out;
138             } else if (ret > 0) {
139                 reply->writeInt32(GATEKEEPER_RESPONSE_RETRY);
140                 reply->writeInt32(ret);
141             } else {
142                 reply->writeInt32(GATEKEEPER_RESPONSE_ERROR);
143             }
144             return NO_ERROR;
145         }
146         case GET_SECURE_USER_ID: {
147             CHECK_INTERFACE(IGateKeeperService, data, reply);
148             uint32_t uid = data.readInt32();
149             uint64_t sid = getSecureUserId(uid);
150             reply->writeNoException();
151             reply->writeInt64(sid);
152             return NO_ERROR;
153         }
154         case CLEAR_SECURE_USER_ID: {
155             CHECK_INTERFACE(IGateKeeperService, data, reply);
156             uint32_t uid = data.readInt32();
157             clearSecureUserId(uid);
158             reply->writeNoException();
159             return NO_ERROR;
160         }
161         default:
162             return BBinder::onTransact(code, data, reply, flags);
163     }
164 };
165 
166 
167 }; // namespace android
168