blob: d38b924310ebf42bd4dac285dff8d84a36fa0a58 [file] [log] [blame]
/*
* Copyright (c) 2013 .SE (The Internet Infrastructure Foundation)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*****************************************************************************
common.h
Common definitions for SoftHSMv2 dump.
*****************************************************************************/
#ifndef _SOFTHSM_V2_COMMON_H
#define _SOFTHSM_V2_COMMON_H
#include <config.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <map>
#include <set>
#include <string>
#include <stdexcept>
#include <vector>
#include "tables.h"
// Table of attribute types
std::map<unsigned long, std::string> CKA_table;
// Dump an attribute type
void dumpCKA(unsigned long cka, int size)
{
// Lazy fill
if (CKA_table.empty())
{
fill_CKA_table(CKA_table);
}
std::string msg;
try
{
msg = CKA_table.at(cka);
printf("%.*s", size, msg.c_str());
}
catch (const std::out_of_range&)
{
if (cka & CKA_VENDOR_DEFINED)
{
cka &= ~CKA_VENDOR_DEFINED;
printf("CKA_VENDOR_DEFINED | 0x%lx", cka);
}
else
{
printf("unknown 0x%lx", cka);
}
}
}
// Table of mechanism types
std::map<unsigned long, std::string> CKM_table;
// Dump a mechanism type
void dumpCKM(unsigned long cka, int size)
{
// Lazy fill
if (CKM_table.empty())
{
fill_CKM_table(CKM_table);
}
std::string msg;
try
{
msg = CKM_table.at(cka);
printf("%.*s", size, msg.c_str());
}
catch (const std::out_of_range&)
{
if (cka & CKM_VENDOR_DEFINED)
{
cka &= ~CKM_VENDOR_DEFINED;
printf("CKM_VENDOR_DEFINED | 0x%lx", cka);
}
else
{
printf("unknown 0x%lx", cka);
}
}
}
// Table of object classes
std::map<unsigned long, std::string> CKO_table;
// Dump a object class
void dumpCKO(unsigned long cka, int size)
{
// Lazy fill
if (CKO_table.empty())
{
fill_CKO_table(CKO_table);
}
std::string msg;
try
{
msg = CKO_table.at(cka);
printf("%.*s", size, msg.c_str());
}
catch (const std::out_of_range&)
{
if (cka & CKO_VENDOR_DEFINED)
{
cka &= ~CKO_VENDOR_DEFINED;
printf("CKO_VENDOR_DEFINED | 0x%lx", cka);
}
else
{
printf("unknown 0x%lx", cka);
}
}
}
// Table of hw feature types
std::map<unsigned long, std::string> CKH_table;
// Dump a hw feature type
void dumpCKH(unsigned long cka, int size)
{
// Lazy fill
if (CKH_table.empty())
{
fill_CKH_table(CKH_table);
}
std::string msg;
try
{
msg = CKH_table.at(cka);
printf("%.*s", size, msg.c_str());
}
catch (const std::out_of_range&)
{
if (cka & CKH_VENDOR_DEFINED)
{
cka &= ~CKH_VENDOR_DEFINED;
printf("CKH_VENDOR_DEFINED | 0x%lx", cka);
}
else
{
printf("unknown 0x%lx", cka);
}
}
}
// Table of key types
std::map<unsigned long, std::string> CKK_table;
// Dump a key type
void dumpCKK(unsigned long cka, int size)
{
// Lazy fill
if (CKK_table.empty())
{
fill_CKK_table(CKK_table);
}
std::string msg;
try
{
msg = CKK_table.at(cka);
printf("%.*s", size, msg.c_str());
}
catch (const std::out_of_range&)
{
if (cka & CKK_VENDOR_DEFINED)
{
cka &= ~CKK_VENDOR_DEFINED;
printf("CKK_VENDOR_DEFINED | 0x%lx", cka);
}
else
{
printf("unknown 0x%lx", cka);
}
}
}
// Table of certificate types
std::map<unsigned long, std::string> CKC_table;
// Dump a certificate type
void dumpCKC(unsigned long cka, int size)
{
// Lazy fill
if (CKC_table.empty())
{
fill_CKC_table(CKC_table);
}
std::string msg;
try
{
msg = CKC_table.at(cka);
printf("%.*s", size, msg.c_str());
}
catch (const std::out_of_range&)
{
if (cka & CKC_VENDOR_DEFINED)
{
cka &= ~CKC_VENDOR_DEFINED;
printf("CKC_VENDOR_DEFINED | 0x%lx", cka);
}
else
{
printf("unknown 0x%lx", cka);
}
}
}
// Dump a PKCS#11 integer type
void dumpCKx(uint64_t cka, uint64_t value, int size)
{
if ((uint32_t)value == (uint32_t)~0)
{
printf("CK_UNAVAILABLE_INFORMATION");
return;
}
switch ((unsigned long) cka)
{
case CKA_CLASS:
if ((uint64_t)((uint32_t)value) != value)
{
printf("overflow object class");
break;
}
dumpCKO((unsigned long) value, size);
break;
case CKA_CERTIFICATE_TYPE:
if ((uint64_t)((uint32_t)value) != value)
{
printf("overflow certificate type");
break;
}
dumpCKC((unsigned long) value, size);
break;
case CKA_KEY_TYPE:
if ((uint64_t)((uint32_t)value) != value)
{
printf("overflow key type");
break;
}
dumpCKK((unsigned long) value, size);
break;
case CKA_KEY_GEN_MECHANISM:
if ((uint64_t)((uint32_t)value) != value)
{
printf("overflow mechanism type");
break;
}
dumpCKM((unsigned long) value, size);
break;
case CKA_HW_FEATURE_TYPE:
if ((uint64_t)((uint32_t)value) != value)
{
printf("overflow hw feature type");
break;
}
dumpCKH((unsigned long) value, size);
break;
default:
printf("CK_ULONG %lu(0x%lx)",
(unsigned long) value,
(unsigned long) value);
break;
}
}
// Dump a boolean (in fact unsigned 8 bit long) value, true is 0xff
void dumpBool(uint8_t value, bool inArray = false)
{
printf("%02hhx %s", value, inArray ? " " : "");
switch (value)
{
case 0:
printf("FALSE");
break;
case 0xff:
printf("TRUE");
break;
default:
printf("(invalid) TRUE");
break;
}
}
// Dump a boolean (in fact unsigned 8 bit long) value, true is 1
void dumpBool1(uint8_t value, bool inArray = false)
{
printf("%02hhx %s", value, inArray ? " " : "");
switch (value)
{
case 0:
printf("FALSE");
break;
case 1:
printf("TRUE");
break;
default:
printf("(invalid) TRUE");
break;
}
}
// Dump an unsigned 64 bit long value
void dumpULong(uint64_t value, bool inArray = false)
{
for (int i = 56; i >= 0; i -= 8)
{
uint8_t v;
v = (value >> i) & 0xff;
printf("%02hhx ", v);
}
if (inArray)
{
printf(" ");
}
}
// Dump an unsigned 32 bit long value
void dumpU32(uint32_t value, bool inArray = false)
{
for (int i = 24; i >= 0; i -= 8)
{
uint8_t v;
v = (value >> i) & 0xff;
printf("%02hhx ", v);
}
printf(" ");
if (inArray)
{
printf(" ");
}
}
// Dump a byte string (aka uint8_t vector) value
void dumpBytes(const std::vector<uint8_t>& value, bool inArray = false)
{
size_t len = value.size();
size_t i = 0;
while (i + 8 <= len)
{
for (size_t j = 0; j < 8; j++)
{
printf("%02hhx ", value[i + j]);
}
if (inArray)
{
printf(" ");
}
printf("<");
for (size_t j = 0; j < 8; j++)
{
uint8_t c = value[i + j];
if (isgraph((int) c) == 0)
{
printf(".");
}
else
{
printf("%c", (int) c);
}
}
printf(">\n");
i += 8;
}
len -= i;
if (len == 0)
{
return;
}
for (size_t j = 0; j < len; j++)
{
printf("%02hhx ", value[i + j]);
}
for (size_t j = len; j < 8; j++)
{
printf(" ");
}
if (inArray)
{
printf(" ");
}
printf("<");
for (size_t j = 0; j < len; j++)
{
uint8_t c = value[i + j];
if (isgraph((int) c) == 0)
{
printf(".");
}
else
{
printf("%c", (int) c);
}
}
for (size_t j =len; j < 8; j++)
{
printf(" ");
}
printf(">\n");
}
// Attribute (in an array) template
template<typename T, typename K, typename I>
class AttributeTK
{
public:
T type;
K kind;
uint8_t boolValue;
I ulongValue;
std::vector<uint8_t> bytestrValue;
std::set<I> mechSetValue;
// Dump an array (in fact an Attribute vector) value
void dumpType() const;
void dumpKind() const;
void dumpBoolValue() const;
void dumpULongValue(I value) const;
bool isBoolean() const;
bool isInteger() const;
bool isBinary() const;
bool isMechSet() const;
void dump() const {
dumpType();
if ((sizeof(type) > 4) &&
((uint64_t)((uint32_t)type) != type))
{
printf("overflow attribute type\n");
}
else
{
dumpCKA((unsigned long) type, 47);
printf("\n");
}
dumpKind();
if (isBoolean())
{
printf("boolean attribute\n");
dumpBoolValue();
printf("\n");
}
else if (isInteger())
{
printf("unsigned long attribute\n");
dumpULongValue(ulongValue);
dumpCKx(type, ulongValue, 47);
printf("\n");
}
else if (isBinary())
{
printf("byte string attribute\n");
I size = bytestrValue.size();
dumpULongValue(size);
printf("(length %lu)\n", (unsigned long) size);
dumpBytes(bytestrValue, true);
}
else if (isMechSet())
{
printf("mechanism set attribute\n");
I size = mechSetValue.size();
dumpULongValue(size);
printf("(length %lu)\n", (unsigned long) size);
for (typename std::set<I>::const_iterator i = mechSetValue.begin(); i != mechSetValue.end(); ++i)
{
dumpULongValue(*i);
dumpCKM(*i, 47);
printf("\n");
}
}
else
{
printf("unknown attribute format\n");
}
}
};
#endif // !_SOFTHSM_V2_COMMON_H