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
22namespace android {
23
24const android::String16 IGateKeeperService::descriptor("android.service.gatekeeper.IGateKeeperService");
25const android::String16& IGateKeeperService::getInterfaceDescriptor() const {
26    return IGateKeeperService::descriptor;
27}
28
29status_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        case REPORT_DEVICE_SETUP_COMPLETE: {
162            CHECK_INTERFACE(IGateKeeperService, data, reply);
163            reportDeviceSetupComplete();
164            reply->writeNoException();
165            return NO_ERROR;
166        }
167        default:
168            return BBinder::onTransact(code, data, reply, flags);
169    }
170};
171
172
173}; // namespace android
174