// // Copyright (c) ANSCENTER. All rights reserved. // #include "precomp.h" #include "anslicensing.h" #include "template.h" #include "base64.h" #include "except.h" #include "uniconv.h" #include "tinyxml2.h" #include "picojson.h" using namespace std; const unsigned char LicenseTemplateImpl::m_demoPublicKeys[10][23] = { {8, 0x67, 0xC9, 0x0C, 0xB9, 0xF9, 0x7D, 0x1C, 0x9C}, {11, 0x76, 0x8C, 0x73, 0xC8, 0xC3, 0x6E, 0xEE, 0x7E, 0x3A, 0xC2, 0x13}, {12, 0xC2, 0x8F, 0x03, 0x24, 0x4B, 0xAF, 0xC7, 0x94, 0x20, 0x3D, 0x46, 0x03}, {13, 0xC8, 0xC3, 0x75, 0x6A, 0x9E, 0x74, 0x5F, 0xC9, 0x18, 0xCF, 0xA0, 0xD4, 0xA9}, {14, 0x75, 0xD5, 0x7F, 0xDC, 0x08, 0x48, 0x93, 0x55, 0xDF, 0x63, 0xF9, 0xC4, 0x2C, 0x48}, {14, 0xE1, 0x5A, 0xA2, 0xE0, 0xB7, 0x33, 0xFF, 0x88, 0x20, 0xFF, 0x1F, 0x91, 0xC9, 0x77}, {17, 0xCC, 0x50, 0x01, 0x33, 0x11, 0x20, 0xFF, 0xA8, 0xED, 0x4F, 0xF2, 0x0A, 0xD7, 0xCB, 0xD0, 0xC3, 0x14}, {18, 0x5A, 0xCC, 0xFB, 0xF5, 0x00, 0x62, 0xB5, 0x6B, 0xEE, 0x28, 0xE3, 0x92, 0x56, 0x2C, 0xAD, 0x76, 0xB8, 0xAE}, {20, 0x4B, 0x36, 0x14, 0x2C, 0x29, 0xF0, 0x0C, 0xCD, 0x2F, 0xC2, 0xE0, 0x24, 0x4A, 0x6E, 0xCA, 0x83, 0x7B, 0xA7, 0xB1, 0x05}, {22, 0x6B, 0x3C, 0x1D, 0xD7, 0x6F, 0xAC, 0x59, 0x37, 0xAA, 0xCC, 0x52, 0xF9, 0xBB, 0x7B, 0x25, 0x34, 0x93, 0x40, 0x7D, 0xE0, 0x90, 0x07} }; const unsigned char LicenseTemplateImpl::m_demoPrivateKeys[10][23] = { {7, 0x5B, 0x3C, 0x97, 0xDC, 0x58, 0x4C, 0x37}, {9, 0xC3, 0xD3, 0xB3, 0xE7, 0x13, 0x0E, 0xC2, 0x46, 0x2F}, {10, 0x25, 0x72, 0x41, 0x0A, 0x22, 0x8E, 0x88, 0x25, 0x1C, 0x01}, {12, 0x23, 0x5F, 0xA9, 0x40, 0x61, 0x5A, 0xB6, 0xC9, 0x07, 0x86, 0x1E, 0x01}, {12, 0x24, 0x2F, 0x29, 0xA7, 0xE1, 0xAF, 0xC1, 0x42, 0x41, 0x82, 0xAF, 0x67}, {13, 0xA8, 0x89, 0x6A, 0x64, 0x85, 0x9D, 0x00, 0xBC, 0x06, 0x92, 0xF0, 0xF9, 0x08}, {15, 0x00, 0x8F, 0x7E, 0x9F, 0x61, 0x38, 0x8B, 0xB3, 0x9D, 0x2D, 0x68, 0x17, 0x7E, 0x7D, 0x19}, {17, 0xBE, 0x53, 0x27, 0xF2, 0xB4, 0xD6, 0xA0, 0xA8, 0xF9, 0x10, 0x67, 0x94, 0x61, 0xD9, 0x8B, 0x4B, 0x03}, {18, 0x0E, 0x15, 0xCB, 0xFC, 0x8D, 0x6C, 0x93, 0xA3, 0x1F, 0x70, 0xB8, 0xFB, 0x25, 0xB4, 0xB8, 0xE1, 0xED, 0x04}, {20, 0x66, 0x8C, 0xE8, 0x03, 0x44, 0x4E, 0x5C, 0x81, 0x15, 0xBF, 0x01, 0x07, 0x6A, 0xA3, 0x59, 0xF6, 0xE0, 0x97, 0x76, 0x45} }; #define TEMPLATE "LicenseKeyTemplate" #define FORMAT "LicenseKey" #define DATA "Data" #define FIELD "Field" #define SIGNATURE "Signature" #define SIGNATURE_PUBLIC_KEY "SignaturePublicKey" #define SIGNATURE_PRIVATE_KEY "SignaturePrivateKey" #define SIGNING_SERVICE_URL "SigningServiceUrl" #define SIGNING_SERVICE_TEMPLATE_ID "SigningServiceTemplateId" #define DATA_FIELDS "DataFields" #define VALIDATION_FIELDS "ValidationFields" void LicenseTemplateImpl::LoadXml(const char * xmlTemplate) { tinyxml2::XMLDocument xml; if (xml.Parse(xmlTemplate) != tinyxml2::XML_NO_ERROR) throw new LicensingException(STATUS_OUT_OF_MEMORY); std::string rootElementName; const char * attr; tinyxml2::XMLElement * element, * rootElement; if ((element = rootElement = xml.FirstChildElement()) == NULL) throw new LicensingException(STATUS_OUT_OF_MEMORY); rootElementName = rootElement->Name(); int templateVersion; if ((attr = element->Attribute("version")) == NULL) templateVersion = 1; else templateVersion = atoi(attr); if (templateVersion < 1 && templateVersion > 3) throw new LicensingException(STATUS_GENERIC_ERROR, "unsupported template version"); if ((element = element->FirstChildElement("LicenseKey")) == NULL) throw new LicensingException(STATUS_OUT_OF_MEMORY); m_keyEncoding = ENCODING_BASE32X; if ((attr = element->Attribute("encoding")) != NULL) if (_stricmp(attr, "base64") == 0) m_keyEncoding = ENCODING_BASE64X; if ((attr = element->Attribute("characterGroups")) == NULL) throw new LicensingException(STATUS_OUT_OF_MEMORY); m_numGroups = atoi(attr); if ((attr = element->Attribute("charactersPerGroup")) == NULL) throw new LicensingException(STATUS_OUT_OF_MEMORY); m_charsPerGroup = atoi(attr); m_groupSeparator = "-"; if ((attr = element->Attribute("groupSeparator")) != NULL) m_groupSeparator = attr; m_header = ""; if ((attr = element->Attribute("header")) != NULL) m_header = attr; m_footer = ""; if ((attr = element->Attribute("footer")) != NULL) m_footer = attr; int type, offset, size; if ((element = xml.FirstChildElement()) == NULL) throw new LicensingException(STATUS_GENERIC_ERROR); if ((element = element->FirstChildElement("LicenseKey")) == NULL) throw new LicensingException(STATUS_GENERIC_ERROR); if ((element = element->FirstChildElement("Data")) == NULL) throw new LicensingException(STATUS_GENERIC_ERROR); if ((element = element->FirstChildElement("DataFields")) == NULL) throw new LicensingException(STATUS_GENERIC_ERROR); for (element = element->FirstChildElement("Field"); element != NULL; element = element->NextSiblingElement()) { attr = element->Attribute("type"); if ( _stricmp( attr, "raw" ) == 0 ) type = FIELD_TYPE_RAW; else if ( _stricmp( attr, "integer" ) == 0 ) type = FIELD_TYPE_INTEGER; else if ( _stricmp( attr, "string" ) == 0 ) type = FIELD_TYPE_STRING; else if ( _stricmp( attr, "date13") == 0 ) type = FIELD_TYPE_DATE13; else if ( _stricmp( attr, "date14" ) == 0 ) type = FIELD_TYPE_DATE14; else if ( _stricmp( attr, "date16" ) == 0 ) type = FIELD_TYPE_DATE16; else throw new LicensingException(STATUS_GENERIC_ERROR); offset = 0; if ((attr = element->Attribute("offset")) != NULL ) { offset = atoi(attr); } if ((attr = element->Attribute("size")) == NULL ) throw new LicensingException(STATUS_GENERIC_ERROR); size = atoi(attr); if ((attr = element->Attribute("name")) == NULL) throw new LicensingException(STATUS_GENERIC_ERROR); m_dataFields.emplace(piecewise_construct, forward_as_tuple(attr), forward_as_tuple(type, size, offset)); } if ((element = xml.FirstChildElement()) == NULL) throw new LicensingException(STATUS_GENERIC_ERROR); if ((element = element->FirstChildElement("LicenseKey")) == NULL) throw new LicensingException(STATUS_GENERIC_ERROR); if ((element = element->FirstChildElement("Data")) == NULL) throw new LicensingException(STATUS_GENERIC_ERROR); if ((element = element->FirstChildElement("ValidationFields")) == NULL) throw new LicensingException(STATUS_GENERIC_ERROR); m_validationDataSize = 0; for (element = element->FirstChildElement("Field"); element != NULL; element = element->NextSiblingElement()) { attr = element->Attribute("type"); if ( _stricmp( attr, "raw" ) == 0 ) type = FIELD_TYPE_RAW; else if ( _stricmp( attr, "integer" ) == 0 ) type = FIELD_TYPE_INTEGER; else if ( _stricmp( attr, "string" ) == 0 ) type = FIELD_TYPE_STRING; else if ( _stricmp ( attr, "date13" ) == 0 ) type = FIELD_TYPE_DATE13; else if ( _stricmp( attr, "date14" ) == 0 ) type = FIELD_TYPE_DATE14; else if ( _stricmp( attr, "date16" ) == 0 ) type = FIELD_TYPE_DATE16; else throw new LicensingException(STATUS_GENERIC_ERROR); offset = 0; if ((attr = element->Attribute("offset")) != NULL ) { offset = atoi(attr); } if ((attr = element->Attribute("size")) == NULL ) throw new LicensingException(STATUS_GENERIC_ERROR); size = atoi(attr); if ((attr = element->Attribute("name")) == NULL) throw new LicensingException(STATUS_GENERIC_ERROR); m_validationFields.emplace(piecewise_construct, forward_as_tuple(attr), forward_as_tuple(type, size, offset)); if (m_validationDataSize < offset + size) m_validationDataSize = offset + size; } if ((element = xml.FirstChildElement()) == NULL) throw new LicensingException(STATUS_GENERIC_ERROR); if ((element = element->FirstChildElement("LicenseKey")) == NULL) throw new LicensingException(STATUS_GENERIC_ERROR); if ((element = element->FirstChildElement("Signature")) == NULL) throw new LicensingException(STATUS_GENERIC_ERROR); if ((attr = element->Attribute("size")) == NULL) throw new LicensingException(STATUS_GENERIC_ERROR, "signature size not provided in template"); int signatureSize = atoi(attr); if (signatureSize <= 0) throw new LicensingException(STATUS_GENERIC_ERROR, "invalid signature size"); SetSignatureSize(signatureSize); SetDataSize((m_numGroups * m_charsPerGroup * m_keyEncoding) - signatureSize); tinyxml2::XMLElement * element2; if ((element2 = element->FirstChildElement("SignaturePrivateKey")) != NULL) { if (templateVersion == 1) { m_signingKey = make_unique(element2->GetText(), m_signatureKeyType); int len = 1024; void * buf = _alloca(1024); if (!m_signingKey->Store(buf, &len)) throw new LicensingException(STATUS_GENERIC_ERROR, "invalid private key"); ValidatePrivateKey(buf, len); } else if (templateVersion <= 3) SetPrivateKey(element2->GetText()); else throw new LicensingException(STATUS_GENERIC_ERROR, "unsupported template version"); } if ((element2 = element->FirstChildElement("SignaturePublicKey")) != NULL) { if (templateVersion == 1) { m_verificationKey = make_unique(element2->GetText(), m_signatureKeyType); m_certificate.reset(Certificate::Generate(signatureSize, m_signingKey.get(), m_verificationKey.get(), NULL, NULL, NULL, 0)); ValidateCertificate(); } else if (templateVersion <= 3) SetPublicKeyCertificate(element2->GetText()); else throw new LicensingException(STATUS_GENERIC_ERROR, "unsupported template version"); } if ((element2 = element->FirstChildElement("SigningServiceUrl")) != NULL) SetLicensingServiceUrl(element2->GetText()); if ((element2 = element->FirstChildElement("SigningServiceTemplateId")) != NULL) SetTemplateId(element2->GetText()); if (templateVersion < 3) return; if ((element = rootElement->FirstChildElement("Properties")) != NULL) { m_properties.LoadXml(element); } } #ifndef MAX_XML_BUFFER_SIZE #define MAX_XML_BUFFER_SIZE 4096 #endif const char * LicenseTemplateImpl::SaveXml(bool savePrivateKey) { BASE64 base64; char buffer[ MAX_XML_BUFFER_SIZE ]; m_xmlTemplate.resize(0); snprintf(buffer, MAX_XML_BUFFER_SIZE, "\n");m_xmlTemplate.append(buffer); snprintf(buffer, MAX_XML_BUFFER_SIZE, "\n", m_version);m_xmlTemplate.append(buffer); snprintf(buffer, MAX_XML_BUFFER_SIZE, "\t\n", (m_keyEncoding == ENCODING_BASE64X) ? "BASE64" : "BASE32X", m_numGroups, m_charsPerGroup, m_groupSeparator.c_str(), m_header.c_str(), m_footer.c_str());m_xmlTemplate.append(buffer); snprintf(buffer, MAX_XML_BUFFER_SIZE, "\t\t\n");m_xmlTemplate.append(buffer); snprintf(buffer, MAX_XML_BUFFER_SIZE, "\t\t\t\n", m_dataSize);m_xmlTemplate.append(buffer); const char * name; BitStruct::FIELD_TYPE type; int size, offset; string fieldType; for (const auto& field : m_dataFields) { name = field.first.c_str(); type = field.second.type; size = field.second.size; offset = field.second.offset; switch ((int)type) { case FIELD_TYPE_INTEGER: fieldType = "Integer"; break; case FIELD_TYPE_STRING: fieldType = "String"; break; case FIELD_TYPE_RAW: fieldType = "Raw"; break; case FIELD_TYPE_DATE13: fieldType = "Date13"; break; case FIELD_TYPE_DATE14: fieldType = "Date14"; break; case FIELD_TYPE_DATE16: fieldType = "Date16"; break; default: fieldType = "Raw"; } snprintf(buffer, MAX_XML_BUFFER_SIZE, "\t\t\t\t\n", name, fieldType.c_str(), size, offset); m_xmlTemplate.append(buffer); } snprintf(buffer, MAX_XML_BUFFER_SIZE, "\t\t\t\n");m_xmlTemplate.append(buffer); snprintf(buffer, MAX_XML_BUFFER_SIZE, "\t\t\t\n");m_xmlTemplate.append(buffer); for (const auto& field : m_validationFields) { name = field.first.c_str(); type = field.second.type; size = field.second.size; offset = field.second.offset; switch ((int)type) { case FIELD_TYPE_INTEGER: fieldType = "Integer"; break; case FIELD_TYPE_STRING: fieldType = "String"; break; case FIELD_TYPE_RAW: fieldType = "Raw"; break; case FIELD_TYPE_DATE13: fieldType = "Date13"; break; case FIELD_TYPE_DATE14: fieldType = "Date14"; break; case FIELD_TYPE_DATE16: fieldType = "Date16"; break; default: fieldType = "Raw"; } snprintf(buffer, MAX_XML_BUFFER_SIZE, "\t\t\t\t\n", name, fieldType.c_str(), size, offset); m_xmlTemplate.append(buffer); } snprintf(buffer, MAX_XML_BUFFER_SIZE, "\t\t\t\n");m_xmlTemplate.append(buffer); snprintf(buffer, MAX_XML_BUFFER_SIZE, "\t\t\n");m_xmlTemplate.append(buffer); snprintf(buffer, MAX_XML_BUFFER_SIZE, "\t\t\n", m_signatureSize);m_xmlTemplate.append(buffer); if (m_certificate) { snprintf(buffer, MAX_XML_BUFFER_SIZE, "\t\t\t%s\n", m_certificate->ToString() );m_xmlTemplate.append(buffer); if (savePrivateKey && m_signingKey) { snprintf(buffer, MAX_XML_BUFFER_SIZE, "\t\t\t%s\n", m_signingKey->ToString() );m_xmlTemplate.append(buffer); } } if (m_licensingServiceUrl.length() > 0) { snprintf(buffer, MAX_XML_BUFFER_SIZE, "\t\t\t%s\n", m_licensingServiceUrl.c_str() );m_xmlTemplate.append(buffer); } if (!m_templateId.empty()) { snprintf(buffer, MAX_XML_BUFFER_SIZE, "\t\t\t%s\n", m_templateId.c_str() );m_xmlTemplate.append(buffer); } snprintf(buffer, MAX_XML_BUFFER_SIZE, "\t\t\n");m_xmlTemplate.append(buffer); snprintf(buffer, MAX_XML_BUFFER_SIZE, "\t\n");m_xmlTemplate.append(buffer); snprintf(buffer, MAX_XML_BUFFER_SIZE, "\t\n");m_xmlTemplate.append(buffer); m_properties.SaveXml(m_xmlTemplate); snprintf(buffer, MAX_XML_BUFFER_SIZE, "\t\n");m_xmlTemplate.append(buffer); snprintf(buffer, MAX_XML_BUFFER_SIZE, "");m_xmlTemplate.append(buffer); return m_xmlTemplate.c_str(); } void LicenseTemplateImpl::LoadJson(const char * xmlTemplate) { picojson::value json; try { std::string err = picojson::parse(json, xmlTemplate); if (!err.empty()) throw new LicensingException(STATUS_GENERIC_ERROR, err.c_str()); if (!json.is()) throw new LicensingException(STATUS_GENERIC_ERROR, "invalid license template"); picojson::object obj = json.get(); int templateVersion = 1; try { templateVersion = obj["version"].get(); } catch (std::out_of_range &) {} if (templateVersion < 1 && templateVersion > 3) throw new LicensingException(STATUS_GENERIC_ERROR, "unsupported template version"); m_keyEncoding = ENCODING_BASE32X; try { if (obj["encoding"].is() && obj["encoding"].get().compare("base64") == 0) m_keyEncoding = ENCODING_BASE64X; } catch (std::out_of_range &) {} m_numGroups = obj["char_groups"].get(); m_charsPerGroup = obj["chars_per_group"].get(); m_groupSeparator = obj["group_sep"].get().c_str(); m_header = obj["header"].get().c_str(); m_footer = obj["footer"].get().c_str(); std::string name; int type, size, offset; picojson::object field; picojson::array fieldList = obj["data_fields"].get(); for (picojson::array::iterator iter = fieldList.begin(); iter != fieldList.end(); iter++) { field = iter->get(); name = field["type"].get(); if ((name.compare("raw") == 0) || (name.compare("Raw") == 0)) type = FIELD_TYPE_RAW; else if ((name.compare("int") == 0) || (name.compare("integer") == 0) || (name.compare("Integer") == 0)) type = FIELD_TYPE_INTEGER; else if ((name.compare("string") == 0) || (name.compare("String") == 0)) type = FIELD_TYPE_STRING; else if ((name.compare("date13") == 0) || (name.compare("Date13") == 0)) type = FIELD_TYPE_DATE13; else if ((name.compare("date14") == 0) || (name.compare("Date14") == 0)) type = FIELD_TYPE_DATE14; else if ((name.compare("date16") == 0) || (name.compare("Date16") == 0)) type = FIELD_TYPE_DATE16; else throw new LicensingException(STATUS_GENERIC_ERROR); name = field["name"].get(); size = field["size"].get(); offset = 0; try { offset = field["offset"].get(); } catch (std::out_of_range &) {} m_dataFields.emplace(piecewise_construct, forward_as_tuple(name.c_str()), forward_as_tuple(type, size, offset)); } m_validationDataSize = 0; if (obj["validation_fields"].is()) { fieldList = obj["validation_fields"].get(); for (picojson::array::iterator iter = fieldList.begin(); iter != fieldList.end(); iter++) { field = iter->get(); name = field["type"].get(); if ((name.compare("raw") == 0) || (name.compare("Raw") == 0)) type = FIELD_TYPE_RAW; else if ((name.compare("int") == 0) || (name.compare("integer") == 0) || (name.compare("Integer") == 0)) type = FIELD_TYPE_INTEGER; else if ((name.compare("string") == 0) || (name.compare("String") == 0)) type = FIELD_TYPE_STRING; else if ((name.compare("date13") == 0) || (name.compare("Date13") == 0)) type = FIELD_TYPE_DATE13; else if ((name.compare("date14") == 0) || (name.compare("Date14") == 0)) type = FIELD_TYPE_DATE14; else if ((name.compare("date16") == 0) || (name.compare("Date16") == 0)) type = FIELD_TYPE_DATE16; else throw new LicensingException(STATUS_GENERIC_ERROR); name = field["name"].get(); size = field["size"].get(); offset = 0; try { offset = field["offset"].get(); } catch (std::out_of_range &) {} m_validationFields.emplace(piecewise_construct, forward_as_tuple(name.c_str()), forward_as_tuple(type, size, offset)); if (m_validationDataSize < offset + size) m_validationDataSize = offset + size; } } SetSignatureSize(obj["signature_size"].get()); SetDataSize((m_numGroups * m_charsPerGroup * m_keyEncoding) - m_signatureSize); if (obj["private_key"].is()) SetPrivateKey(obj["private_key"].get()["k"].get().c_str()); if (obj["public_cert"].is()) SetPublicKeyCertificate(obj["public_cert"].get()["p"].get().c_str()); if (obj["licensing_service_url"].is()) SetLicensingServiceUrl(obj["licensing_service_url"].get().c_str()); if (obj["licensing_service_template_id"].is()) SetTemplateId(obj["licensing_service_template_id"].get().c_str()); if (obj["properties"].is()) m_properties.LoadJson(obj["properties"].get()); } catch (std::exception & e) { throw new LicensingException(STATUS_GENERIC_ERROR, "error loading JSON license template"); } } #ifndef MAX_JSON_BUFFER_SIZE #define MAX_JSON_BUFFER_SIZE 4096 #endif const char * LicenseTemplateImpl::SaveJson(bool savePrivateKey) { BASE64 base64; char buffer[MAX_XML_BUFFER_SIZE]; m_xmlTemplate.resize(0); snprintf(buffer, MAX_XML_BUFFER_SIZE, "{" "\n\t\"version\":%d" ",\n\t\"encoding\":\"%s\"" ",\n\t\"char_groups\":%d" ",\n\t\"chars_per_group\":%d" ",\n\t\"group_sep\":\"%s\"" ",\n\t\"header\":\"%s\"" ",\n\t\"footer\":\"%s\"" ",\n\t\"data_size\":%d", m_version, (m_keyEncoding == ENCODING_BASE64X) ? "BASE64" : "BASE32X", m_numGroups, m_charsPerGroup, m_groupSeparator.c_str(), m_header.c_str(), m_footer.c_str(), m_dataSize); m_xmlTemplate.append(buffer); snprintf(buffer, MAX_XML_BUFFER_SIZE, ",\n\t\"data_fields\":["); m_xmlTemplate.append(buffer); const char * name; BitStruct::FIELD_TYPE type; int size, offset; string fieldType; bool first = true; for (const auto& field : m_dataFields) { name = field.first.c_str(); type = field.second.type; size = field.second.size; offset = field.second.offset; if (!first) m_xmlTemplate.append(","); switch ((int)type) { case FIELD_TYPE_INTEGER: fieldType = "int"; break; case FIELD_TYPE_STRING: fieldType = "string"; break; case FIELD_TYPE_RAW: fieldType = "raw"; break; case FIELD_TYPE_DATE13: fieldType = "date13"; break; case FIELD_TYPE_DATE14: fieldType = "date14"; break; case FIELD_TYPE_DATE16: fieldType = "date16"; break; default: fieldType = "raw"; } snprintf(buffer, MAX_XML_BUFFER_SIZE, "\n\t\t{ \"name\":\"%s\", \"type\":\"%s\", \"size\":%d, \"offset\":%d }", name, fieldType.c_str(), size, offset); m_xmlTemplate.append(buffer); first = false; } snprintf(buffer, MAX_XML_BUFFER_SIZE, "\n\t]"); m_xmlTemplate.append(buffer); snprintf(buffer, MAX_XML_BUFFER_SIZE, ",\n\t\"validation_data_size\":%d", m_validationDataSize); m_xmlTemplate.append(buffer); snprintf(buffer, MAX_XML_BUFFER_SIZE, ",\n\t\"validation_fields\":["); m_xmlTemplate.append(buffer); first = true; for (const auto& field : m_validationFields) { name = field.first.c_str(); type = field.second.type; size = field.second.size; offset = field.second.offset; if (!first) m_xmlTemplate.append(","); switch ((int)type) { case FIELD_TYPE_INTEGER: fieldType = "int"; break; case FIELD_TYPE_STRING: fieldType = "string"; break; case FIELD_TYPE_RAW: fieldType = "raw"; break; case FIELD_TYPE_DATE13: fieldType = "date13"; break; case FIELD_TYPE_DATE14: fieldType = "date14"; break; case FIELD_TYPE_DATE16: fieldType = "date16"; break; default: fieldType = "raw"; } snprintf(buffer, MAX_XML_BUFFER_SIZE, "\n\t\t{ \"name\":\"%s\", \"type\":\"%s\", \"size\":%d, \"offset\":%d }", name, fieldType.c_str(), size, offset); m_xmlTemplate.append(buffer); first = false; } snprintf(buffer, MAX_XML_BUFFER_SIZE, "\n\t]"); m_xmlTemplate.append(buffer); snprintf(buffer, MAX_XML_BUFFER_SIZE, ",\n\t\"signature_size\":%d", m_signatureSize); m_xmlTemplate.append(buffer); if (m_certificate) { snprintf(buffer, MAX_XML_BUFFER_SIZE, ",\n\t\"public_cert\": {\"kty\":\"softactivate_ec_v1\", \"p\":\"%s\"}", m_certificate->ToString()); m_xmlTemplate.append(buffer); if (savePrivateKey && m_signingKey) { snprintf(buffer, MAX_XML_BUFFER_SIZE, ",\n\t\"private_key\": {\"kty\":\"softactivate_ec_v1\", \"k\":\"%s\"}", m_signingKey->ToString()); m_xmlTemplate.append(buffer); } } if (m_licensingServiceUrl.length() > 0) { snprintf(buffer, MAX_XML_BUFFER_SIZE, ",\n\t\"licensing_service_url\":\"%s\"", m_licensingServiceUrl.c_str()); m_xmlTemplate.append(buffer); } if (!m_templateId.empty()) { snprintf(buffer, MAX_XML_BUFFER_SIZE, ",\n\t\"licensing_service_template_id\":\"%s\"", m_templateId.c_str()); m_xmlTemplate.append(buffer); } if (m_properties.GetSize() > 0) { snprintf(buffer, MAX_XML_BUFFER_SIZE, ",\n\t\"properties\":"); m_xmlTemplate.append(buffer); m_properties.SaveJson(m_xmlTemplate, "\t"); } snprintf(buffer, MAX_XML_BUFFER_SIZE, "\n}"); m_xmlTemplate.append(buffer); return m_xmlTemplate.c_str(); } namespace ANSCENTER { namespace Licensing { template<> LicenseTemplateT::LicenseTemplateT(): m_Impl(*(new LicenseTemplateImpl())) { } template<> LicenseTemplateT::LicenseTemplateT(): m_Impl(*(new LicenseTemplateImpl())) { } template<> LicenseTemplateT::~LicenseTemplateT() { delete & m_Impl; } template<> LicenseTemplateT::~LicenseTemplateT() { delete & m_Impl; } template<> LicenseTemplateT * LicenseTemplateT::Create() { return new LicenseTemplateT(); } template<> LicenseTemplateT * LicenseTemplateT::Create() { return new LicenseTemplateT(); } template<> void LicenseTemplateT::Destroy(LicenseTemplateT * obj) { delete obj; } template<> void LicenseTemplateT::Destroy(LicenseTemplateT * obj) { delete obj; } template<> void LicenseTemplateT::SetNumberOfGroups(int numGroups) { m_Impl.SetNumberOfGroups(numGroups); } template<> void LicenseTemplateT::SetNumberOfGroups(int numGroups) { m_Impl.SetNumberOfGroups(numGroups); } template<> unsigned LicenseTemplateT::GetNumberOfGroups() { return m_Impl.GetNumberOfGroups(); } template<> unsigned LicenseTemplateT::GetNumberOfGroups() { return m_Impl.GetNumberOfGroups(); } template<> void LicenseTemplateT::SetCharactersPerGroup(int charsPerGroup) { m_Impl.SetCharactersPerGroup(charsPerGroup); } template<> void LicenseTemplateT::SetCharactersPerGroup(int charsPerGroup) { m_Impl.SetCharactersPerGroup(charsPerGroup); } template<> unsigned LicenseTemplateT::GetCharactersPerGroup() { return m_Impl.GetCharactersPerGroup(); } template<> unsigned LicenseTemplateT::GetCharactersPerGroup() { return m_Impl.GetCharactersPerGroup(); } template<> void LicenseTemplateT::SetGroupSeparator(const char * groupSep) { m_Impl.SetGroupSeparator(groupSep); } template<> void LicenseTemplateT::SetGroupSeparator(const wchar_t * groupSep) { m_Impl.SetGroupSeparator(w2s(groupSep).c_str()); } template<> const char * LicenseTemplateT::GetGroupSeparator() { return m_Impl.GetGroupSeparator(); } template<> const wchar_t * LicenseTemplateT::GetGroupSeparator() { static wstring wstr1; wstr1 = s2w(m_Impl.GetGroupSeparator()); return wstr1.c_str(); } template<> void LicenseTemplateT::SetEncoding(int encoding) { m_Impl.SetEncoding(encoding); } template<> void LicenseTemplateT::SetEncoding(int encoding) { m_Impl.SetEncoding(encoding); } template<> int LicenseTemplateT::GetEncoding() { return m_Impl.GetEncoding(); } template<> int LicenseTemplateT::GetEncoding() { return m_Impl.GetEncoding(); } template<> void LicenseTemplateT::SetHeader(const char * header) { m_Impl.SetHeader(header); } template<> void LicenseTemplateT::SetHeader(const wchar_t * header) { m_Impl.SetHeader(w2s(header).c_str()); } template<> const char * LicenseTemplateT::GetHeader() { return m_Impl.GetHeader(); } template<> const wchar_t * LicenseTemplateT::GetHeader() { static wstring wstr1; wstr1 = s2w(m_Impl.GetHeader()); return wstr1.c_str(); } template<> void LicenseTemplateT::SetFooter(const char * footer) { m_Impl.SetFooter(footer); } template<> void LicenseTemplateT::SetFooter(const wchar_t * footer) { m_Impl.SetFooter(w2s(footer).c_str()); } template<> const char * LicenseTemplateT::GetFooter() { return m_Impl.GetFooter(); } template<> const wchar_t * LicenseTemplateT::GetFooter() { static wstring wstr1; wstr1 = s2w(m_Impl.GetFooter()); return wstr1.c_str(); } template<> void LicenseTemplateT::SetDataSize(int sizeInBits) { m_Impl.SetDataSize(sizeInBits); } template<> void LicenseTemplateT::SetDataSize(int sizeInBits) { m_Impl.SetDataSize(sizeInBits); } template<> unsigned LicenseTemplateT::GetDataSize() { return m_Impl.GetDataSize(); } template<> unsigned LicenseTemplateT::GetDataSize() { return m_Impl.GetDataSize(); } template<> void LicenseTemplateT::AddDataField(const char * fieldName, int fieldType, int fieldBitSize, int offset) { m_Impl.AddDataField(fieldName, fieldType, fieldBitSize, offset); } template<> void LicenseTemplateT::AddDataField(const wchar_t * fieldName, int fieldType, int fieldBitSize, int offset) { m_Impl.AddDataField(w2s(fieldName).c_str(), fieldType, fieldBitSize, offset); } template<> bool LicenseTemplateT::GetDataField(const wchar_t * fieldName, int * fieldType, int * fieldBitSize, int * offset) { return m_Impl.GetDataField(w2s(fieldName).c_str(), fieldType, fieldBitSize, offset); } template<> bool LicenseTemplateT::GetDataField(const char * fieldName, int * fieldType, int * fieldBitSize, int * offset) { return m_Impl.GetDataField(fieldName, fieldType, fieldBitSize, offset); } template<> bool LicenseTemplateT::EnumDataFields(void **enumHandle, const char **fieldName, int * fieldType, int * fieldSize, int * offset) { return m_Impl.EnumDataFields(enumHandle, fieldName, fieldType, fieldSize, offset); } template<> bool LicenseTemplateT::EnumDataFields(void **enumHandle, const wchar_t **fieldName, int * fieldType, int * fieldSize, int * offset) { const char * name; static std::wstring staticName; bool result = m_Impl.EnumDataFields(enumHandle, &name, fieldType, fieldSize, offset); if (result) { staticName = s2w(name); *fieldName = staticName.c_str(); } return result; } template<> void LicenseTemplateT::SetValidationDataSize(int sizeInBits) { m_Impl.SetValidationDataSize(sizeInBits); } template<> void LicenseTemplateT::SetValidationDataSize(int sizeInBits) { m_Impl.SetValidationDataSize(sizeInBits); } template<> unsigned LicenseTemplateT::GetValidationDataSize() { return m_Impl.GetValidationDataSize(); } template<> unsigned LicenseTemplateT::GetValidationDataSize() { return m_Impl.GetValidationDataSize(); } template<> void LicenseTemplateT::AddValidationField(const char * fieldName, int fieldType, int fieldBitSize, int offset) { m_Impl.AddValidationField(fieldName, fieldType, fieldBitSize, offset); } template<> void LicenseTemplateT::AddValidationField(const wchar_t * fieldName, int fieldType, int fieldBitSize, int offset) { m_Impl.AddValidationField(w2s(fieldName).c_str(), fieldType, fieldBitSize, offset); } template<> bool LicenseTemplateT::EnumValidationFields(void **enumHandle, const char **fieldName, int * fieldType, int * fieldSize, int * offset) { return m_Impl.EnumValidationFields(enumHandle, fieldName, fieldType, fieldSize, offset); } template<> bool LicenseTemplateT::EnumValidationFields(void **enumHandle, const wchar_t **fieldName, int * fieldType, int * fieldSize, int * offset) { const char * name; static std::wstring staticName; bool result = m_Impl.EnumValidationFields(enumHandle, &name, fieldType, fieldSize, offset); if (result) { staticName = s2w(name); *fieldName = staticName.c_str(); } return result; } template<> bool LicenseTemplateT::GetValidationField(const wchar_t * fieldName, int * fieldType, int * fieldBitSize, int * offset) { return m_Impl.GetValidationField(w2s(fieldName).c_str(), fieldType, fieldBitSize, offset); } template<> bool LicenseTemplateT::GetValidationField(const char * fieldName, int * fieldType, int * fieldBitSize, int * offset) { return m_Impl.GetValidationField(fieldName, fieldType, fieldBitSize, offset); } template<> void LicenseTemplateT::SetSignatureSize(int signatureSize) { m_Impl.SetSignatureSize(signatureSize); } template<> void LicenseTemplateT::SetSignatureSize(int signatureSize) { m_Impl.SetSignatureSize(signatureSize); } template<> unsigned LicenseTemplateT::GetSignatureSize() { return m_Impl.GetSignatureSize(); } template<> unsigned LicenseTemplateT::GetSignatureSize() { return m_Impl.GetSignatureSize(); } template<> void LicenseTemplateT::SetVersion(int version) { m_Impl.SetVersion(version); } template<> void LicenseTemplateT::SetVersion(int version) { m_Impl.SetVersion(version); } template<> unsigned LicenseTemplateT::GetVersion() { return m_Impl.GetVersion(); } template<> void LicenseTemplateT::SetTemplateId(const char * templateId) { m_Impl.SetTemplateId(templateId); } template<> void LicenseTemplateT::SetTemplateId(const wchar_t * templateId) { m_Impl.SetTemplateId(w2s(templateId).c_str()); } template<> unsigned LicenseTemplateT::GetVersion() { return m_Impl.GetVersion(); } template<> void LicenseTemplateT::LoadXml(const char * xmlTemplate) { m_Impl.LoadXml(xmlTemplate); } template<> void LicenseTemplateT::LoadXml(const char * xmlTemplate) { m_Impl.LoadXml(xmlTemplate); } template<> const char * LicenseTemplateT::SaveXml(bool savePrivateKey) { return m_Impl.SaveXml(savePrivateKey); } template<> const char * LicenseTemplateT::SaveXml(bool savePrivateKey) { return m_Impl.SaveXml(savePrivateKey); } template<> void LicenseTemplateT::LoadJson(const char * jsonTemplate) { m_Impl.LoadJson(jsonTemplate); } template<> void LicenseTemplateT::LoadJson(const char * jsonTemplate) { m_Impl.LoadJson(jsonTemplate); } template<> const char * LicenseTemplateT::SaveJson(bool savePrivateKey) { return m_Impl.SaveJson(savePrivateKey); } template<> const char * LicenseTemplateT::SaveJson(bool savePrivateKey) { return m_Impl.SaveJson(savePrivateKey); } template<> void LicenseTemplateT::SetLicensingServiceUrl(const char * url) { m_Impl.SetLicensingServiceUrl(url); } template<> void LicenseTemplateT::SetLicensingServiceUrl(const wchar_t * url) { m_Impl.SetLicensingServiceUrl(w2s(url).c_str()); } template<> const char * LicenseTemplateT::GetLicensingServiceUrl() { return m_Impl.GetLicensingServiceUrl(); } template<> const wchar_t * LicenseTemplateT::GetLicensingServiceUrl() { static wstring wstr1; wstr1 = s2w(m_Impl.GetLicensingServiceUrl()); return wstr1.c_str(); } template<> void LicenseTemplateT::SetPublicKeyCertificate(const char * base64Certificate) { m_Impl.SetPublicKeyCertificate(base64Certificate); } template<> void LicenseTemplateT::SetPublicKeyCertificate(const wchar_t * base64Certificate) { m_Impl.SetPublicKeyCertificate(w2s(base64Certificate).c_str()); } template<> const char * LicenseTemplateT::GetPublicKeyCertificate() { return m_Impl.GetPublicKeyCertificate(); } template<> const wchar_t * LicenseTemplateT::GetPublicKeyCertificate() { static wstring wstr1; wstr1 = s2w(m_Impl.GetPublicKeyCertificate()); return wstr1.c_str(); } template<> void LicenseTemplateT::SetPrivateKey(const char * base64Key) { m_Impl.SetPrivateKey(base64Key); } template<> void LicenseTemplateT::SetPrivateKey(const wchar_t * base64Key) { m_Impl.SetPrivateKey(w2s(base64Key).c_str()); } template<> const char * LicenseTemplateT::GetPrivateKey() { return m_Impl.GetPrivateKey(); } template<> const wchar_t * LicenseTemplateT::GetPrivateKey() { static wstring wstr1; wstr1 = s2w(m_Impl.GetPrivateKey()); return wstr1.c_str(); } template<> void LicenseTemplateT::SetProperty(const char * path, const char * name, const char * value) { m_Impl.SetProperty(path, (name) ? name : nullptr, value); } template<> void LicenseTemplateT::SetProperty(const wchar_t * path, const wchar_t * name, const wchar_t * value) { m_Impl.SetProperty(w2s(path).c_str(), (name) ? w2s(name).c_str() : nullptr, w2s(value).c_str()); } template<> const char * LicenseTemplateT::GetProperty(const char * path, const char * name) { return m_Impl.GetProperty(path, name); } template<> const wchar_t * LicenseTemplateT::GetProperty(const wchar_t * path, const wchar_t * name) { static wstring wstr1; wstr1 = s2w(m_Impl.GetProperty(w2s(path).c_str(), w2s(name).c_str())); return wstr1.c_str(); } template<> void LicenseTemplateT::GenerateSigningKeyPair() { m_Impl.GenerateSigningKeyPair(); } template<> void LicenseTemplateT::GenerateSigningKeyPair() { m_Impl.GenerateSigningKeyPair(); } }; };