15187818895c4c5f650a611c40531b1dff7764c18Kenny Root/*
25187818895c4c5f650a611c40531b1dff7764c18Kenny Root * Copyright (C) 2012 The Android Open Source Project
35187818895c4c5f650a611c40531b1dff7764c18Kenny Root *
45187818895c4c5f650a611c40531b1dff7764c18Kenny Root * Licensed under the Apache License, Version 2.0 (the "License");
55187818895c4c5f650a611c40531b1dff7764c18Kenny Root * you may not use this file except in compliance with the License.
65187818895c4c5f650a611c40531b1dff7764c18Kenny Root * You may obtain a copy of the License at
75187818895c4c5f650a611c40531b1dff7764c18Kenny Root *
85187818895c4c5f650a611c40531b1dff7764c18Kenny Root *      http://www.apache.org/licenses/LICENSE-2.0
95187818895c4c5f650a611c40531b1dff7764c18Kenny Root *
105187818895c4c5f650a611c40531b1dff7764c18Kenny Root * Unless required by applicable law or agreed to in writing, software
115187818895c4c5f650a611c40531b1dff7764c18Kenny Root * distributed under the License is distributed on an "AS IS" BASIS,
125187818895c4c5f650a611c40531b1dff7764c18Kenny Root * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135187818895c4c5f650a611c40531b1dff7764c18Kenny Root * See the License for the specific language governing permissions and
145187818895c4c5f650a611c40531b1dff7764c18Kenny Root * limitations under the License.
155187818895c4c5f650a611c40531b1dff7764c18Kenny Root */
165187818895c4c5f650a611c40531b1dff7764c18Kenny Root
175187818895c4c5f650a611c40531b1dff7764c18Kenny Root#include <keystore.h>
185187818895c4c5f650a611c40531b1dff7764c18Kenny Root#include <keystore_client.h>
195187818895c4c5f650a611c40531b1dff7764c18Kenny Root
205187818895c4c5f650a611c40531b1dff7764c18Kenny Root#include <cutils/sockets.h>
215187818895c4c5f650a611c40531b1dff7764c18Kenny Root
225187818895c4c5f650a611c40531b1dff7764c18Kenny Root#define LOG_TAG "keystore_client"
235187818895c4c5f650a611c40531b1dff7764c18Kenny Root#include <cutils/log.h>
245187818895c4c5f650a611c40531b1dff7764c18Kenny Root
255187818895c4c5f650a611c40531b1dff7764c18Kenny RootResponseCode keystore_cmd(command_code_t cmd, Keystore_Reply* reply, int numArgs, ...) {
265187818895c4c5f650a611c40531b1dff7764c18Kenny Root    int sock;
275187818895c4c5f650a611c40531b1dff7764c18Kenny Root
285187818895c4c5f650a611c40531b1dff7764c18Kenny Root    sock = socket_local_client("keystore", ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM);
295187818895c4c5f650a611c40531b1dff7764c18Kenny Root    if (sock == -1) {
305187818895c4c5f650a611c40531b1dff7764c18Kenny Root        return SYSTEM_ERROR;
315187818895c4c5f650a611c40531b1dff7764c18Kenny Root    }
325187818895c4c5f650a611c40531b1dff7764c18Kenny Root
335187818895c4c5f650a611c40531b1dff7764c18Kenny Root    if (TEMP_FAILURE_RETRY(send(sock, &cmd, 1, MSG_NOSIGNAL)) != 1) {
345187818895c4c5f650a611c40531b1dff7764c18Kenny Root        close(sock);
355187818895c4c5f650a611c40531b1dff7764c18Kenny Root        return SYSTEM_ERROR;
365187818895c4c5f650a611c40531b1dff7764c18Kenny Root    }
375187818895c4c5f650a611c40531b1dff7764c18Kenny Root
385187818895c4c5f650a611c40531b1dff7764c18Kenny Root    va_list vl;
395187818895c4c5f650a611c40531b1dff7764c18Kenny Root    va_start(vl, numArgs);
405187818895c4c5f650a611c40531b1dff7764c18Kenny Root    for (int i = 0; i < numArgs; i++) {
415187818895c4c5f650a611c40531b1dff7764c18Kenny Root        size_t argLen = va_arg(vl, size_t);
425187818895c4c5f650a611c40531b1dff7764c18Kenny Root        uint8_t* arg = va_arg(vl, uint8_t*);
435187818895c4c5f650a611c40531b1dff7764c18Kenny Root
445187818895c4c5f650a611c40531b1dff7764c18Kenny Root        if (argLen > KEYSTORE_MESSAGE_SIZE) {
455187818895c4c5f650a611c40531b1dff7764c18Kenny Root            ALOGE("code called us with an argLen out of bounds: %llu", (unsigned long long) argLen);
465187818895c4c5f650a611c40531b1dff7764c18Kenny Root            close(sock);
475187818895c4c5f650a611c40531b1dff7764c18Kenny Root            return SYSTEM_ERROR;
485187818895c4c5f650a611c40531b1dff7764c18Kenny Root        }
495187818895c4c5f650a611c40531b1dff7764c18Kenny Root
505187818895c4c5f650a611c40531b1dff7764c18Kenny Root        uint8_t bytes[2] = { argLen >> 8, argLen };
515187818895c4c5f650a611c40531b1dff7764c18Kenny Root        if (TEMP_FAILURE_RETRY(send(sock, bytes, 2, MSG_NOSIGNAL)) != 2
525187818895c4c5f650a611c40531b1dff7764c18Kenny Root                || TEMP_FAILURE_RETRY(send(sock, arg, argLen, MSG_NOSIGNAL))
535187818895c4c5f650a611c40531b1dff7764c18Kenny Root                        != static_cast<ssize_t>(argLen)) {
545187818895c4c5f650a611c40531b1dff7764c18Kenny Root            ALOGW("truncated write to keystore");
555187818895c4c5f650a611c40531b1dff7764c18Kenny Root            close(sock);
565187818895c4c5f650a611c40531b1dff7764c18Kenny Root            return SYSTEM_ERROR;
575187818895c4c5f650a611c40531b1dff7764c18Kenny Root        }
585187818895c4c5f650a611c40531b1dff7764c18Kenny Root    }
595187818895c4c5f650a611c40531b1dff7764c18Kenny Root    va_end(vl);
605187818895c4c5f650a611c40531b1dff7764c18Kenny Root
615187818895c4c5f650a611c40531b1dff7764c18Kenny Root    uint8_t code = 0;
625187818895c4c5f650a611c40531b1dff7764c18Kenny Root    if (shutdown(sock, SHUT_WR) != 0
635187818895c4c5f650a611c40531b1dff7764c18Kenny Root            || TEMP_FAILURE_RETRY(recv(sock, &code, 1, 0)) != 1
645187818895c4c5f650a611c40531b1dff7764c18Kenny Root            || code != NO_ERROR) {
655187818895c4c5f650a611c40531b1dff7764c18Kenny Root        ALOGW("Error from keystore: %d", code);
665187818895c4c5f650a611c40531b1dff7764c18Kenny Root        close(sock);
675187818895c4c5f650a611c40531b1dff7764c18Kenny Root        return SYSTEM_ERROR;
685187818895c4c5f650a611c40531b1dff7764c18Kenny Root    }
695187818895c4c5f650a611c40531b1dff7764c18Kenny Root
705187818895c4c5f650a611c40531b1dff7764c18Kenny Root    if (reply != NULL) {
715187818895c4c5f650a611c40531b1dff7764c18Kenny Root        reply->setCode(static_cast<ResponseCode>(code));
725187818895c4c5f650a611c40531b1dff7764c18Kenny Root
735187818895c4c5f650a611c40531b1dff7764c18Kenny Root        uint8_t bytes[2];
745187818895c4c5f650a611c40531b1dff7764c18Kenny Root        uint8_t* data = reply->get();
755187818895c4c5f650a611c40531b1dff7764c18Kenny Root        if (TEMP_FAILURE_RETRY(recv(sock, &bytes[0], 1, 0)) == 1
765187818895c4c5f650a611c40531b1dff7764c18Kenny Root                && TEMP_FAILURE_RETRY(recv(sock, &bytes[1], 1, 0)) == 1) {
775187818895c4c5f650a611c40531b1dff7764c18Kenny Root            int offset = 0;
785187818895c4c5f650a611c40531b1dff7764c18Kenny Root            int length = bytes[0] << 8 | bytes[1];
795187818895c4c5f650a611c40531b1dff7764c18Kenny Root            while (offset < length) {
805187818895c4c5f650a611c40531b1dff7764c18Kenny Root                int n = TEMP_FAILURE_RETRY(recv(sock, &data[offset], length - offset, 0));
815187818895c4c5f650a611c40531b1dff7764c18Kenny Root                if (n <= 0) {
825187818895c4c5f650a611c40531b1dff7764c18Kenny Root                    ALOGW("truncated read from keystore for data");
835187818895c4c5f650a611c40531b1dff7764c18Kenny Root                    code = SYSTEM_ERROR;
845187818895c4c5f650a611c40531b1dff7764c18Kenny Root                    break;
855187818895c4c5f650a611c40531b1dff7764c18Kenny Root                }
865187818895c4c5f650a611c40531b1dff7764c18Kenny Root                offset += n;
875187818895c4c5f650a611c40531b1dff7764c18Kenny Root            }
885187818895c4c5f650a611c40531b1dff7764c18Kenny Root            reply->setLength(length);
895187818895c4c5f650a611c40531b1dff7764c18Kenny Root        } else {
905187818895c4c5f650a611c40531b1dff7764c18Kenny Root            ALOGW("truncated read from keystore for length");
915187818895c4c5f650a611c40531b1dff7764c18Kenny Root            code = SYSTEM_ERROR;
925187818895c4c5f650a611c40531b1dff7764c18Kenny Root        }
935187818895c4c5f650a611c40531b1dff7764c18Kenny Root    }
945187818895c4c5f650a611c40531b1dff7764c18Kenny Root
955187818895c4c5f650a611c40531b1dff7764c18Kenny Root    close(sock);
965187818895c4c5f650a611c40531b1dff7764c18Kenny Root    return static_cast<ResponseCode>(code);
975187818895c4c5f650a611c40531b1dff7764c18Kenny Root}
985187818895c4c5f650a611c40531b1dff7764c18Kenny Root
995187818895c4c5f650a611c40531b1dff7764c18Kenny RootKeystore_Reply::Keystore_Reply()
1005187818895c4c5f650a611c40531b1dff7764c18Kenny Root        : mCode(SYSTEM_ERROR)
1015187818895c4c5f650a611c40531b1dff7764c18Kenny Root        , mLength(-1) {
1025187818895c4c5f650a611c40531b1dff7764c18Kenny Root    mData = new uint8_t[KEYSTORE_MESSAGE_SIZE];
1035187818895c4c5f650a611c40531b1dff7764c18Kenny Root}
1045187818895c4c5f650a611c40531b1dff7764c18Kenny Root
1055187818895c4c5f650a611c40531b1dff7764c18Kenny RootKeystore_Reply::~Keystore_Reply() {
1065187818895c4c5f650a611c40531b1dff7764c18Kenny Root    delete[] mData;
1075187818895c4c5f650a611c40531b1dff7764c18Kenny Root}
1085187818895c4c5f650a611c40531b1dff7764c18Kenny Root
1095187818895c4c5f650a611c40531b1dff7764c18Kenny Rootuint8_t* Keystore_Reply::get() {
1105187818895c4c5f650a611c40531b1dff7764c18Kenny Root    return mData;
1115187818895c4c5f650a611c40531b1dff7764c18Kenny Root}
1125187818895c4c5f650a611c40531b1dff7764c18Kenny Root
1135187818895c4c5f650a611c40531b1dff7764c18Kenny Rootvoid Keystore_Reply::setLength(size_t length) {
1145187818895c4c5f650a611c40531b1dff7764c18Kenny Root    mLength = length;
1155187818895c4c5f650a611c40531b1dff7764c18Kenny Root}
1165187818895c4c5f650a611c40531b1dff7764c18Kenny Root
1175187818895c4c5f650a611c40531b1dff7764c18Kenny Rootsize_t Keystore_Reply::length() const {
1185187818895c4c5f650a611c40531b1dff7764c18Kenny Root    return mLength;
1195187818895c4c5f650a611c40531b1dff7764c18Kenny Root}
1205187818895c4c5f650a611c40531b1dff7764c18Kenny Root
1215187818895c4c5f650a611c40531b1dff7764c18Kenny Rootvoid Keystore_Reply::setCode(ResponseCode code) {
1225187818895c4c5f650a611c40531b1dff7764c18Kenny Root    mCode = code;
1235187818895c4c5f650a611c40531b1dff7764c18Kenny Root}
1245187818895c4c5f650a611c40531b1dff7764c18Kenny Root
1255187818895c4c5f650a611c40531b1dff7764c18Kenny RootResponseCode Keystore_Reply::code() const {
1265187818895c4c5f650a611c40531b1dff7764c18Kenny Root    return mCode;
1275187818895c4c5f650a611c40531b1dff7764c18Kenny Root}
1285187818895c4c5f650a611c40531b1dff7764c18Kenny Root
1295187818895c4c5f650a611c40531b1dff7764c18Kenny Rootuint8_t* Keystore_Reply::release() {
1305187818895c4c5f650a611c40531b1dff7764c18Kenny Root    uint8_t* data = mData;
1315187818895c4c5f650a611c40531b1dff7764c18Kenny Root    mData = NULL;
1325187818895c4c5f650a611c40531b1dff7764c18Kenny Root    return data;
1335187818895c4c5f650a611c40531b1dff7764c18Kenny Root}
134