keystore_client.cpp revision 5187818895c4c5f650a611c40531b1dff7764c18
1/* 2 * Copyright (C) 2012 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#include <keystore.h> 18#include <keystore_client.h> 19 20#include <cutils/sockets.h> 21 22#define LOG_TAG "keystore_client" 23#include <cutils/log.h> 24 25ResponseCode keystore_cmd(command_code_t cmd, Keystore_Reply* reply, int numArgs, ...) { 26 int sock; 27 28 sock = socket_local_client("keystore", ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM); 29 if (sock == -1) { 30 return SYSTEM_ERROR; 31 } 32 33 if (TEMP_FAILURE_RETRY(send(sock, &cmd, 1, MSG_NOSIGNAL)) != 1) { 34 close(sock); 35 return SYSTEM_ERROR; 36 } 37 38 va_list vl; 39 va_start(vl, numArgs); 40 for (int i = 0; i < numArgs; i++) { 41 size_t argLen = va_arg(vl, size_t); 42 uint8_t* arg = va_arg(vl, uint8_t*); 43 44 if (argLen > KEYSTORE_MESSAGE_SIZE) { 45 ALOGE("code called us with an argLen out of bounds: %llu", (unsigned long long) argLen); 46 close(sock); 47 return SYSTEM_ERROR; 48 } 49 50 uint8_t bytes[2] = { argLen >> 8, argLen }; 51 if (TEMP_FAILURE_RETRY(send(sock, bytes, 2, MSG_NOSIGNAL)) != 2 52 || TEMP_FAILURE_RETRY(send(sock, arg, argLen, MSG_NOSIGNAL)) 53 != static_cast<ssize_t>(argLen)) { 54 ALOGW("truncated write to keystore"); 55 close(sock); 56 return SYSTEM_ERROR; 57 } 58 } 59 va_end(vl); 60 61 uint8_t code = 0; 62 if (shutdown(sock, SHUT_WR) != 0 63 || TEMP_FAILURE_RETRY(recv(sock, &code, 1, 0)) != 1 64 || code != NO_ERROR) { 65 ALOGW("Error from keystore: %d", code); 66 close(sock); 67 return SYSTEM_ERROR; 68 } 69 70 if (reply != NULL) { 71 reply->setCode(static_cast<ResponseCode>(code)); 72 73 uint8_t bytes[2]; 74 uint8_t* data = reply->get(); 75 if (TEMP_FAILURE_RETRY(recv(sock, &bytes[0], 1, 0)) == 1 76 && TEMP_FAILURE_RETRY(recv(sock, &bytes[1], 1, 0)) == 1) { 77 int offset = 0; 78 int length = bytes[0] << 8 | bytes[1]; 79 while (offset < length) { 80 int n = TEMP_FAILURE_RETRY(recv(sock, &data[offset], length - offset, 0)); 81 if (n <= 0) { 82 ALOGW("truncated read from keystore for data"); 83 code = SYSTEM_ERROR; 84 break; 85 } 86 offset += n; 87 } 88 reply->setLength(length); 89 } else { 90 ALOGW("truncated read from keystore for length"); 91 code = SYSTEM_ERROR; 92 } 93 } 94 95 close(sock); 96 return static_cast<ResponseCode>(code); 97} 98 99Keystore_Reply::Keystore_Reply() 100 : mCode(SYSTEM_ERROR) 101 , mLength(-1) { 102 mData = new uint8_t[KEYSTORE_MESSAGE_SIZE]; 103} 104 105Keystore_Reply::~Keystore_Reply() { 106 delete[] mData; 107} 108 109uint8_t* Keystore_Reply::get() { 110 return mData; 111} 112 113void Keystore_Reply::setLength(size_t length) { 114 mLength = length; 115} 116 117size_t Keystore_Reply::length() const { 118 return mLength; 119} 120 121void Keystore_Reply::setCode(ResponseCode code) { 122 mCode = code; 123} 124 125ResponseCode Keystore_Reply::code() const { 126 return mCode; 127} 128 129uint8_t* Keystore_Reply::release() { 130 uint8_t* data = mData; 131 mData = NULL; 132 return data; 133} 134