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