/* * 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 #include #include #include #include #include #include #include #include #include "tables.h" // Table of attribute types std::map 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 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 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 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 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 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& 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 class AttributeTK { public: T type; K kind; uint8_t boolValue; I ulongValue; std::vector bytestrValue; std::set 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::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