blob: 44ca3fdf29b18358927c316174dfdd27e7624de3 [file] [log] [blame]
// Copyright 2017 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chaps/proto_conversion.h"
#include <stdint.h>
#include <string.h>
#include <algorithm>
#include <string>
#include <base/logging.h>
#include <google/protobuf/message_lite.h>
namespace {
bool ProtoToVersion(const chaps::Version& proto, CK_VERSION* out_version) {
DCHECK(out_version);
if (!proto.has_major() || !proto.has_minor())
return false;
out_version->major = static_cast<CK_BYTE>(proto.major());
out_version->minor = static_cast<CK_BYTE>(proto.minor());
return true;
}
void VersionToProto(const CK_VERSION* version, chaps::Version* proto) {
DCHECK(version);
DCHECK(proto);
proto->set_major(static_cast<uint32_t>(version->major));
proto->set_minor(static_cast<uint32_t>(version->minor));
}
void ZeroAndCopy(CK_BYTE* dest, const std::string& src, size_t buf_size) {
memset(dest, 0, buf_size);
memcpy(dest, src.c_str(), std::min(buf_size, src.size()));
}
std::string CopyToString(const CK_BYTE* src, size_t buf_size) {
return std::string(reinterpret_cast<const char*>(src), buf_size);
}
} // namespace
namespace chaps {
bool ProtoToMechanismInfo(const MechanismInfo& proto,
CK_MECHANISM_INFO* out_info) {
DCHECK(out_info);
if (!proto.has_min_key_size() || !proto.has_max_key_size() ||
!proto.has_flags())
return false;
out_info->ulMinKeySize = static_cast<CK_ULONG>(proto.min_key_size());
out_info->ulMaxKeySize = static_cast<CK_ULONG>(proto.max_key_size());
out_info->flags = static_cast<CK_FLAGS>(proto.flags());
return true;
}
MechanismInfo MechanismInfoToProto(const CK_MECHANISM_INFO* info) {
DCHECK(info);
MechanismInfo proto;
proto.set_min_key_size(static_cast<uint64_t>(info->ulMinKeySize));
proto.set_max_key_size(static_cast<uint64_t>(info->ulMaxKeySize));
proto.set_flags(static_cast<uint64_t>(info->flags));
return proto;
}
bool ProtoToSessionInfo(const SessionInfo& proto,
CK_SESSION_INFO* out_info) {
DCHECK(out_info);
if (!proto.has_slot_id() || !proto.has_state() || !proto.has_flags() ||
!proto.has_device_error())
return false;
out_info->slotID = static_cast<CK_SLOT_ID>(proto.slot_id());
out_info->state = static_cast<CK_STATE>(proto.state());
out_info->flags = static_cast<CK_FLAGS>(proto.flags());
out_info->ulDeviceError = static_cast<CK_ULONG>(proto.device_error());
return true;
}
SessionInfo SessionInfoToProto(const CK_SESSION_INFO* info) {
DCHECK(info);
SessionInfo proto;
proto.set_slot_id(static_cast<uint64_t>(info->slotID));
proto.set_state(static_cast<uint64_t>(info->state));
proto.set_flags(static_cast<uint64_t>(info->flags));
proto.set_device_error(static_cast<uint64_t>(info->ulDeviceError));
return proto;
}
bool ProtoToSlotInfo(const SlotInfo& proto, CK_SLOT_INFO* out_info) {
DCHECK(out_info);
if (!proto.has_slot_description() || !proto.has_manufacturer_id() ||
!proto.has_flags() || !proto.has_hardware_version() ||
!proto.has_firmware_version())
return false;
ZeroAndCopy(out_info->slotDescription, proto.slot_description(), 64);
ZeroAndCopy(out_info->manufacturerID, proto.manufacturer_id(), 32);
out_info->flags = static_cast<CK_FLAGS>(proto.flags());
if (!ProtoToVersion(proto.hardware_version(), &out_info->hardwareVersion) ||
!ProtoToVersion(proto.firmware_version(), &out_info->firmwareVersion))
return false;
return true;
}
SlotInfo SlotInfoToProto(const CK_SLOT_INFO* info) {
DCHECK(info);
SlotInfo proto;
proto.set_slot_description(CopyToString(info->slotDescription, 64));
proto.set_manufacturer_id(CopyToString(info->manufacturerID, 32));
proto.set_flags(static_cast<uint64_t>(info->flags));
VersionToProto(&info->hardwareVersion, proto.mutable_hardware_version());
VersionToProto(&info->firmwareVersion, proto.mutable_firmware_version());
return proto;
}
bool ProtoToTokenInfo(const TokenInfo& proto, CK_TOKEN_INFO* out_info) {
DCHECK(out_info);
if (!proto.has_label() || !proto.has_manufacturer_id() ||
!proto.has_model() || !proto.has_serial_number() || !proto.has_flags() ||
!proto.has_max_session_count() || !proto.has_session_count() ||
!proto.has_max_session_count_rw() || !proto.has_session_count_rw() ||
!proto.has_max_pin_len() || !proto.has_min_pin_len() ||
!proto.has_total_public_memory() || !proto.has_free_public_memory() ||
!proto.has_total_private_memory() || !proto.has_free_private_memory() ||
!proto.has_hardware_version() || !proto.has_firmware_version())
return false;
ZeroAndCopy(out_info->label, proto.label(), 32);
ZeroAndCopy(out_info->manufacturerID, proto.manufacturer_id(), 32);
ZeroAndCopy(out_info->model, proto.model(), 16);
ZeroAndCopy(out_info->serialNumber, proto.serial_number(), 16);
out_info->flags = static_cast<CK_FLAGS>(proto.flags());
out_info->ulMaxSessionCount =
static_cast<CK_ULONG>(proto.max_session_count());
out_info->ulSessionCount = static_cast<CK_ULONG>(proto.session_count());
out_info->ulMaxRwSessionCount =
static_cast<CK_ULONG>(proto.max_session_count_rw());
out_info->ulRwSessionCount = static_cast<CK_ULONG>(proto.session_count_rw());
out_info->ulMaxPinLen = static_cast<CK_ULONG>(proto.max_pin_len());
out_info->ulMinPinLen = static_cast<CK_ULONG>(proto.min_pin_len());
out_info->ulTotalPublicMemory =
static_cast<CK_ULONG>(proto.total_public_memory());
out_info->ulFreePublicMemory =
static_cast<CK_ULONG>(proto.free_public_memory());
out_info->ulTotalPrivateMemory =
static_cast<CK_ULONG>(proto.total_private_memory());
out_info->ulFreePrivateMemory =
static_cast<CK_ULONG>(proto.free_private_memory());
if (!ProtoToVersion(proto.hardware_version(), &out_info->hardwareVersion) ||
!ProtoToVersion(proto.firmware_version(), &out_info->firmwareVersion))
return false;
return true;
}
TokenInfo TokenInfoToProto(const CK_TOKEN_INFO* info) {
DCHECK(info);
TokenInfo proto;
proto.set_label(CopyToString(info->label, 32));
proto.set_manufacturer_id(CopyToString(info->manufacturerID, 32));
proto.set_model(CopyToString(info->model, 16));
proto.set_serial_number(CopyToString(info->serialNumber, 16));
proto.set_flags(static_cast<uint64_t>(info->flags));
proto.set_max_session_count(static_cast<uint64_t>(info->ulMaxSessionCount));
proto.set_session_count(static_cast<uint64_t>(info->ulSessionCount));
proto.set_max_session_count_rw(
static_cast<uint64_t>(info->ulMaxRwSessionCount));
proto.set_session_count_rw(static_cast<uint64_t>(info->ulRwSessionCount));
proto.set_max_pin_len(static_cast<uint64_t>(info->ulMaxPinLen));
proto.set_min_pin_len(static_cast<uint64_t>(info->ulMinPinLen));
proto.set_total_public_memory(
static_cast<uint64_t>(info->ulTotalPublicMemory));
proto.set_free_public_memory(static_cast<uint64_t>(info->ulFreePublicMemory));
proto.set_total_private_memory(
static_cast<uint64_t>(info->ulTotalPrivateMemory));
proto.set_free_private_memory(
static_cast<uint64_t>(info->ulFreePrivateMemory));
VersionToProto(&info->hardwareVersion, proto.mutable_hardware_version());
VersionToProto(&info->firmwareVersion, proto.mutable_firmware_version());
return proto;
}
} // namespace chaps