logic: licence error handling
Fixed bug #277 and improved error handling in licence code
This commit is contained in:
@@ -51,6 +51,13 @@ void LicenseChecker::saveCurrentLicenseString(const std::string& licenseString)
|
||||
}
|
||||
|
||||
ApplicationSettings* appSettings = ApplicationSettings::getInstance().get();
|
||||
|
||||
if (appSettings == NULL)
|
||||
{
|
||||
LOG_ERROR_STREAM(<< "Unable to retrieve app settings");
|
||||
return;
|
||||
}
|
||||
|
||||
std::string appPath(AppPath::getAppPath());
|
||||
|
||||
appSettings->setLicenseString(license.getLicenseEncodedString(appPath));
|
||||
@@ -66,10 +73,21 @@ bool LicenseChecker::isCurrentLicenseValid()
|
||||
LicenseChecker::LicenseState LicenseChecker::checkCurrentLicense() const
|
||||
{
|
||||
ApplicationSettings* appSettings = ApplicationSettings::getInstance().get();
|
||||
if (appSettings == NULL)
|
||||
{
|
||||
LOG_ERROR_STREAM(<< "Unable to retrieve app settings");
|
||||
return LICENSE_EMPTY;
|
||||
}
|
||||
|
||||
std::string licenseCheck = appSettings->getLicenseCheck();
|
||||
std::string appPath(AppPath::getAppPath());
|
||||
|
||||
if (appPath.size() <= 0)
|
||||
{
|
||||
LOG_ERROR_STREAM(<< "Failed to retrieve app path");
|
||||
return LICENSE_EMPTY;
|
||||
}
|
||||
|
||||
std::string licenseString = appSettings->getLicenseString();
|
||||
if (licenseString.size() == 0)
|
||||
{
|
||||
|
||||
@@ -64,14 +64,30 @@ std::string Generator::encodeLicense(const std::string& user, const int days)
|
||||
|
||||
std::string Generator::encodeLicense(const std::string& user, const std::string& licenseType)
|
||||
{
|
||||
if (user.size() <= 0)
|
||||
{
|
||||
std::cout << "No user given" << std::endl;
|
||||
return "";
|
||||
}
|
||||
|
||||
if (licenseType.size() <= 0)
|
||||
{
|
||||
std::cout << "No licence type given" << std::endl;
|
||||
return "";
|
||||
}
|
||||
|
||||
License license;
|
||||
|
||||
//load private key
|
||||
std::string filename = getPrivateKeyFilename();
|
||||
|
||||
std::shared_ptr<Botan::Private_Key> privateKey(
|
||||
Botan::PKCS8::load_key(filename, m_rng, PRIVATE_KEY_PASSWORD));
|
||||
|
||||
Botan::RSA_PrivateKey *rsaKey = dynamic_cast<Botan::RSA_PrivateKey *>(privateKey.get());
|
||||
if (!rsaKey) {
|
||||
|
||||
if (!rsaKey)
|
||||
{
|
||||
std::cout << "The key is not a RSA key" << std::endl;
|
||||
}
|
||||
|
||||
@@ -114,51 +130,85 @@ std::string Generator::getPublicKeyPEMFileAsString()
|
||||
|
||||
std::string Generator::getPrivateKeyPEMFileAsString()
|
||||
{
|
||||
if (m_privateKey == NULL)
|
||||
{
|
||||
std::cout << "m_privateKey is NULL" << std::endl;
|
||||
return "";
|
||||
}
|
||||
|
||||
return Botan::PKCS8::PEM_encode(*m_privateKey, m_rng, PRIVATE_KEY_PASSWORD);
|
||||
}
|
||||
|
||||
void Generator::writeKeysToFiles()
|
||||
{
|
||||
//public key
|
||||
std::string filename = getPublicKeyFilename();
|
||||
std::cout << "publickey filename: " << filename << std::endl;
|
||||
std::ofstream pub(filename);
|
||||
std::string publicKeyFilename = getPublicKeyFilename();
|
||||
if (publicKeyFilename.size() <= 0)
|
||||
{
|
||||
std::cout << "Failed to retrieve file name for public key" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
std::string privateKeyFilename = getPrivateKeyFilename();
|
||||
if (privateKeyFilename.size() <= 0)
|
||||
{
|
||||
std::cout << "Failed to retrieve file name for private key" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
std::cout << "public key filename: " << publicKeyFilename << std::endl;
|
||||
std::ofstream pub(publicKeyFilename);
|
||||
pub << getPublicKeyPEMFileAsString();
|
||||
std::cout << "public key created" << std::endl;
|
||||
// private key
|
||||
filename = getPrivateKeyFilename();
|
||||
std::cout << "publickey filename: " << filename << std::endl;
|
||||
std::ofstream priv(filename);
|
||||
|
||||
std::cout << "private key filename: " << privateKeyFilename << std::endl;
|
||||
std::ofstream priv(privateKeyFilename);
|
||||
priv << getPrivateKeyPEMFileAsString();
|
||||
std::cout << "private key created" << std::endl;
|
||||
}
|
||||
|
||||
bool Generator::loadPrivateKeyFromFile()
|
||||
{
|
||||
boost::filesystem::exists(getPrivateKeyFilename());
|
||||
if (boost::filesystem::exists(getPrivateKeyFilename()) == false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Botan::Private_Key* privateKey = Botan::PKCS8::load_key(getPrivateKeyFilename(), m_rng, PRIVATE_KEY_PASSWORD);
|
||||
Botan::RSA_PrivateKey *rsaKey = dynamic_cast<Botan::RSA_PrivateKey *>(privateKey);
|
||||
if (!rsaKey) {
|
||||
|
||||
if (!rsaKey)
|
||||
{
|
||||
std::cout << "The key is not a RSA key" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_privateKey = std::shared_ptr<Botan::RSA_PrivateKey>(rsaKey);
|
||||
|
||||
return true;
|
||||
return (m_privateKey != NULL);
|
||||
}
|
||||
|
||||
bool Generator::loadPrivateKeyFromString(const std::string& key)
|
||||
{
|
||||
if (key.size() <= 0)
|
||||
{
|
||||
std::cout << "No key string given" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
Botan::DataSource_Memory in(key);
|
||||
Botan::Private_Key* privateKey= Botan::PKCS8::load_key(in, m_rng, PRIVATE_KEY_PASSWORD);
|
||||
Botan::RSA_PrivateKey *rsaKey = dynamic_cast<Botan::RSA_PrivateKey *>(privateKey);
|
||||
if (!rsaKey) {
|
||||
|
||||
if (!rsaKey)
|
||||
{
|
||||
std::cout << "The key is not a RSA key" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_privateKey = std::shared_ptr<Botan::RSA_PrivateKey>(rsaKey);
|
||||
|
||||
return true;
|
||||
return (m_privateKey != NULL);
|
||||
}
|
||||
|
||||
Botan::RSA_PrivateKey *Generator::getPrivateKey() const
|
||||
|
||||
@@ -31,7 +31,7 @@ public:
|
||||
bool loadPrivateKeyFromFile();
|
||||
bool loadPrivateKeyFromString(const std::string& key);
|
||||
|
||||
void PrintLicense();
|
||||
// void PrintLicense(); // not implemented, is this deprecated or something?
|
||||
|
||||
Botan::RSA_PrivateKey* getPrivateKey() const;
|
||||
|
||||
|
||||
+212
-61
@@ -21,7 +21,7 @@
|
||||
|
||||
namespace
|
||||
{
|
||||
std::string trim(const std::string &str)
|
||||
std::string trimWhiteSpaces(const std::string &str)
|
||||
{
|
||||
auto wsfront = std::find_if_not(str.begin(), str.end(), [](int c){ return std::isspace(c); });
|
||||
auto wsback = std::find_if_not(str.rbegin(), str.rend(), [](int c){ return std::isspace(c); }).base();
|
||||
@@ -40,54 +40,112 @@ License::~License()
|
||||
|
||||
std::string License::getHashLine() const
|
||||
{
|
||||
return lines[4];
|
||||
if (m_lines.size() >= 5)
|
||||
{
|
||||
return m_lines[4];
|
||||
}
|
||||
else
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
std::string License::getMessage() const
|
||||
{
|
||||
std::string message = "";
|
||||
for(int i = 1; i < 5; ++i)
|
||||
|
||||
if (m_lines.size() >= 5)
|
||||
{
|
||||
message += lines[i];
|
||||
for (int i = 1; i < 5; ++i)
|
||||
{
|
||||
message += m_lines[i];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
message = "";
|
||||
}
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
std::string License::getSignature() const
|
||||
{
|
||||
std::string signatue = "";
|
||||
for(int i = 5; i < 12; ++i)
|
||||
|
||||
if (m_lines.size() >= 12)
|
||||
{
|
||||
signatue += lines[i];
|
||||
for (int i = 5; i < 12; ++i)
|
||||
{
|
||||
signatue += m_lines[i];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
signatue = "";
|
||||
}
|
||||
|
||||
return signatue;
|
||||
}
|
||||
|
||||
std::string License::getVersionLine() const
|
||||
{
|
||||
return lines[3];
|
||||
if (m_lines.size() >= 3)
|
||||
{
|
||||
return m_lines[3];
|
||||
}
|
||||
else
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
std::string License::getOwnerLine() const
|
||||
{
|
||||
return lines[1];
|
||||
if (m_lines.size() >= 1)
|
||||
{
|
||||
return m_lines[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
std::string License::getLicenseTypeLine() const
|
||||
{
|
||||
return lines[2];
|
||||
if (m_lines.size() >= 2)
|
||||
{
|
||||
return m_lines[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
int License::getTimeLeft() const
|
||||
{
|
||||
const std::string testText = "Test License - valid till ";
|
||||
if(getLicenseTypeLine().substr(0, testText.length()) == testText)
|
||||
const int leMagicNumber = 11;
|
||||
|
||||
std::string licenceType = getLicenseTypeLine();
|
||||
|
||||
if (licenceType.size() <= (testText.length() + leMagicNumber))
|
||||
{
|
||||
return -2; // well, since it's unclear what type of licence...??
|
||||
}
|
||||
|
||||
if(licenceType.substr(0, testText.length()) == testText)
|
||||
{
|
||||
std::string dateString = licenceType.substr(testText.length(), leMagicNumber);
|
||||
|
||||
boost::gregorian::date expireDate(
|
||||
boost::gregorian::from_simple_string(getLicenseTypeLine().substr(testText.length(),11))
|
||||
);
|
||||
boost::gregorian::from_simple_string(dateString));
|
||||
|
||||
boost::gregorian::date today = boost::gregorian::day_clock::local_day();
|
||||
boost::gregorian::days daysLeft = expireDate - today;
|
||||
|
||||
return (daysLeft.days() < 0 ? -1 : daysLeft.days());
|
||||
}
|
||||
else
|
||||
@@ -106,30 +164,33 @@ void License::create(
|
||||
//encode message
|
||||
Botan::PK_Signer signer(*privateKey, *(m_rng.get()), "EMSA4(SHA-256)");
|
||||
Botan::DataSource_Memory in(getMessage());
|
||||
Botan::byte buf[4096] = {0};
|
||||
while (size_t got = in.read(buf, sizeof(buf))) {
|
||||
signer.update(buf, got);
|
||||
Botan::byte buffer[4096] = {0};
|
||||
|
||||
while (size_t got = in.read(buffer, sizeof(buffer)))
|
||||
{
|
||||
signer.update(buffer, got); // the hell does 'got' stand for?
|
||||
}
|
||||
|
||||
std::string signature = Botan::base64_encode(signer.signature(*(m_rng.get())));
|
||||
addSignature(signature);
|
||||
}
|
||||
|
||||
void License::createMessage(const std::string& user, const std::string& version, const std::string& type)
|
||||
{
|
||||
lines.clear();
|
||||
lines.push_back(BEGIN_LICENSE);
|
||||
lines.push_back(user);
|
||||
lines.push_back(type);
|
||||
m_lines.clear();
|
||||
m_lines.push_back(BEGIN_LICENSE);
|
||||
m_lines.push_back(user);
|
||||
m_lines.push_back(type);
|
||||
std::string versionstring = "Coati " + getVersion();
|
||||
lines.push_back(versionstring);
|
||||
m_lines.push_back(versionstring);
|
||||
std::string pass9 = Botan::generate_passhash9(versionstring, *(m_rng.get()));
|
||||
lines.push_back(pass9);
|
||||
m_lines.push_back(pass9);
|
||||
}
|
||||
|
||||
void License::writeToFile(const std::string& filename)
|
||||
{
|
||||
std::ofstream licenseFile(filename);
|
||||
for(std::string line : lines)
|
||||
for(std::string line : m_lines)
|
||||
{
|
||||
licenseFile << line << std::endl;
|
||||
}
|
||||
@@ -137,38 +198,44 @@ void License::writeToFile(const std::string& filename)
|
||||
|
||||
bool License::loadFromString(const std::string& licenseText)
|
||||
{
|
||||
lines.clear();
|
||||
m_lines.clear();
|
||||
std::istringstream license(licenseText);
|
||||
return load(license);
|
||||
}
|
||||
|
||||
bool License::load(std::istream& stream)
|
||||
{
|
||||
lines.clear();
|
||||
m_lines.clear();
|
||||
std::string line;
|
||||
|
||||
while (getline(stream, line, '\n'))
|
||||
{
|
||||
std::string l = trim(line);
|
||||
std::string l = trimWhiteSpaces(line);
|
||||
if (l.size())
|
||||
{
|
||||
lines.push_back(l);
|
||||
m_lines.push_back(l);
|
||||
}
|
||||
}
|
||||
|
||||
if (lines.front() != BEGIN_LICENSE)
|
||||
if (m_lines.size() <= 0)
|
||||
{
|
||||
std::cout << "Could not read licence, possible empty string or only white spaces" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_lines.front() != BEGIN_LICENSE)
|
||||
{
|
||||
std::cout << "No License Header" << std::endl;
|
||||
lines.insert(lines.begin(), BEGIN_LICENSE);
|
||||
m_lines.insert(m_lines.begin(), BEGIN_LICENSE);
|
||||
}
|
||||
|
||||
if (lines.back() != END_LICENSE)
|
||||
if (m_lines.back() != END_LICENSE)
|
||||
{
|
||||
std::cout << "No License Footer" << std::endl;
|
||||
lines.push_back(END_LICENSE);
|
||||
m_lines.push_back(END_LICENSE);
|
||||
}
|
||||
|
||||
if (lines.size() != 13)
|
||||
if (m_lines.size() != 13)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -178,7 +245,7 @@ bool License::load(std::istream& stream)
|
||||
|
||||
bool License::loadFromFile(const std::string& filename)
|
||||
{
|
||||
lines.clear();
|
||||
m_lines.clear();
|
||||
std::ifstream sigfile(filename);
|
||||
return load(sigfile);
|
||||
}
|
||||
@@ -190,26 +257,31 @@ void License::print()
|
||||
|
||||
void License::addSignature(const std::string& signature)
|
||||
{
|
||||
if(lines.size() > 5)
|
||||
if(m_lines.size() > 5)
|
||||
{
|
||||
std::cout << "signature already there" << std::endl;
|
||||
return;
|
||||
}
|
||||
if (!signature.size()) {
|
||||
if (signature.size() <= 0)
|
||||
{
|
||||
std::cout << "signature is empty." << std::endl;
|
||||
return;
|
||||
}
|
||||
std::stringstream ss;
|
||||
for (size_t i = 0; i < signature.size(); i++) {
|
||||
if(i % 55 == 0 && i != 0)
|
||||
|
||||
const int leMagicNumber = 55; // what does this number mean? signature length?
|
||||
for (size_t i = 0; i < signature.size(); i++)
|
||||
{
|
||||
if(i % leMagicNumber == 0 && i != 0)
|
||||
{
|
||||
lines.push_back(ss.str());
|
||||
m_lines.push_back(ss.str());
|
||||
ss.str("");
|
||||
}
|
||||
ss << signature[i];
|
||||
}
|
||||
lines.push_back(ss.str());
|
||||
lines.push_back(END_LICENSE);
|
||||
|
||||
m_lines.push_back(ss.str());
|
||||
m_lines.push_back(END_LICENSE); // why is this done here? the function name indicates only adding of signature
|
||||
}
|
||||
|
||||
bool License::isValid() const
|
||||
@@ -219,33 +291,46 @@ bool License::isValid() const
|
||||
std::cout << "No public key loaded" << std::endl;
|
||||
return false;
|
||||
}
|
||||
try
|
||||
try // lol, now we try to handle errors?
|
||||
{
|
||||
|
||||
// why is this still here?
|
||||
if(Botan::check_passhash9("Coati "+ getVersion(), getHashLine()))
|
||||
{
|
||||
// std::cout << "Hash from Coati "+ getVersion() + " confirmed" << std::endl;
|
||||
}
|
||||
|
||||
Botan::secure_vector<Botan::byte> sig = Botan::base64_decode(getSignature());
|
||||
std::string signatureString = getSignature();
|
||||
if (signatureString.size() <= 0)
|
||||
{
|
||||
std::cout << "Could not read signature" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
Botan::secure_vector<Botan::byte> signature = Botan::base64_decode(signatureString);
|
||||
|
||||
if (m_publicKey == NULL)
|
||||
{
|
||||
std::cout << "Public key is NULL" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
Botan::PK_Verifier verifier(*m_publicKey.get(), "EMSA4(SHA-256)");
|
||||
|
||||
Botan::DataSource_Memory in(getMessage());
|
||||
Botan::byte buf[4096] = {0};
|
||||
while(size_t got = in.read(buf, sizeof(buf)))
|
||||
Botan::byte buffer[4096] = {0};
|
||||
while(size_t got = in.read(buffer, sizeof(buffer)))
|
||||
{
|
||||
verifier.update(buf, got);
|
||||
verifier.update(buffer, got); // what does 'got' stand for?
|
||||
}
|
||||
|
||||
const bool ok = verifier.check_signature(sig);
|
||||
const bool ok = verifier.check_signature(signature);
|
||||
if (isExpired())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
catch(...)
|
||||
catch(...) // invalid character, or something else... why not check what the exception is?
|
||||
{
|
||||
std::cout << "Invalid character in Licensekey" << std::endl;
|
||||
}
|
||||
@@ -277,30 +362,45 @@ std::string License::getVersion() const
|
||||
|
||||
bool License::loadPublicKeyFromFile(const std::string& filename)
|
||||
{
|
||||
if (!filename.empty()) {
|
||||
if (!filename.empty())
|
||||
{
|
||||
m_publicKeyFilename = filename;
|
||||
}
|
||||
|
||||
if(boost::filesystem::exists(getPublicKeyFilename()))
|
||||
{
|
||||
Botan::RSA_PublicKey *rsaPublicKey = dynamic_cast<Botan::RSA_PublicKey *>(Botan::X509::load_key(getPublicKeyFilename()));
|
||||
if (!rsaPublicKey) {
|
||||
|
||||
if (!rsaPublicKey)
|
||||
{
|
||||
std::cout << "The loaded key is not a RSA key" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_publicKey = std::shared_ptr<Botan::RSA_PublicKey>(rsaPublicKey);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool License::loadPublicKeyFromString(const std::string& publicKey)
|
||||
{
|
||||
if (publicKey.empty())
|
||||
{
|
||||
std::cout << "Public key is empty" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
Botan::DataSource_Memory in(publicKey);
|
||||
Botan::RSA_PublicKey *rsaPublicKey = dynamic_cast<Botan::RSA_PublicKey *>(Botan::X509::load_key(in));
|
||||
if (!rsaPublicKey) {
|
||||
|
||||
if (!rsaPublicKey)
|
||||
{
|
||||
std::cout << "The loaded key is not a RSA key" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_publicKey = std::shared_ptr<Botan::RSA_PublicKey>(rsaPublicKey);
|
||||
return true;
|
||||
}
|
||||
@@ -316,7 +416,7 @@ void License::setVersion(const std::string& version)
|
||||
std::string License::getLicenseString() const
|
||||
{
|
||||
std::stringstream license;
|
||||
for(std::string line : lines)
|
||||
for(std::string line : m_lines)
|
||||
{
|
||||
license << line << std::endl;
|
||||
}
|
||||
@@ -325,60 +425,111 @@ std::string License::getLicenseString() const
|
||||
|
||||
std::string License::hashLocation(const std::string& location)
|
||||
{
|
||||
if (m_rng == NULL || location.size() <= 0)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
return Botan::generate_passhash9(location, *(m_rng.get()));
|
||||
}
|
||||
|
||||
bool License::checkLocation(const std::string& location, const std::string& hash)
|
||||
{
|
||||
if (location.size() <= 0 || hash.size() <= 0)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
return Botan::check_passhash9(location, hash);
|
||||
}
|
||||
|
||||
std::string License::getLicenseEncodedString(const std::string& applicationLocation) const
|
||||
{
|
||||
if (applicationLocation.size() <= 0)
|
||||
{
|
||||
std::cout << "No application location was given" << std::endl;
|
||||
return "";
|
||||
}
|
||||
|
||||
Botan::AutoSeeded_RNG rng;
|
||||
std::vector<Botan::byte> file_contents;
|
||||
std::vector<Botan::byte> fileContents;
|
||||
std::stringstream input(getLicenseString());
|
||||
|
||||
//prepare the license string to work with the botan cryptobox
|
||||
while(input.good())
|
||||
{
|
||||
Botan::byte filebuf[4096] = { 0 };
|
||||
input.read((char*)filebuf, sizeof(filebuf));
|
||||
size_t got = input.gcount();
|
||||
Botan::byte filebuffer[4096] = { 0 };
|
||||
input.read((char*)filebuffer, sizeof(filebuffer));
|
||||
size_t got = input.gcount(); // what does got stand for?
|
||||
|
||||
file_contents.insert(file_contents.end(), filebuf, filebuf+got);
|
||||
fileContents.insert(fileContents.end(), filebuffer, filebuffer + got);
|
||||
}
|
||||
|
||||
if(fileContents.size() <= 0)
|
||||
{
|
||||
std::cout << "Failed to read licence string" << std::endl;
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string ret = Botan::CryptoBox::encrypt(&file_contents[0], file_contents.size(),getEncodeKey(applicationLocation),rng);
|
||||
std::string result = Botan::CryptoBox::encrypt(&fileContents[0], fileContents.size(), getEncodeKey(applicationLocation), rng);
|
||||
|
||||
//remove Botan Cryptobox begin and end
|
||||
//should not be in the application settings
|
||||
ret = ret.substr(40,ret.length()-78);
|
||||
const int leMagicNumberA = 40;
|
||||
const int leMagicNumberB = 78;
|
||||
|
||||
return ret;
|
||||
if (result.length() < leMagicNumberA + leMagicNumberB)
|
||||
{
|
||||
std::cout << "Invalid result" << std::endl;
|
||||
return "";
|
||||
}
|
||||
|
||||
result = result.substr(leMagicNumberA, result.length() - leMagicNumberB);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool License::loadFromEncodedString(const std::string& encodedLicense, const std::string& applicationLocation)
|
||||
{
|
||||
try {
|
||||
if (encodedLicense.size() <= 0)
|
||||
{
|
||||
std::cout << "No licence string given" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (applicationLocation.size() <= 0)
|
||||
{
|
||||
std::cout << "No application location given" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
//add cryptobox begin and end to loaded string
|
||||
std::string crypbobxInput = "-----BEGIN BOTAN CRYPTOBOX MESSAGE-----\n";
|
||||
crypbobxInput += encodedLicense;
|
||||
crypbobxInput += "-----END BOTAN CRYPTOBOX MESSAGE-----";
|
||||
|
||||
//decrypt license
|
||||
loadFromString(Botan::CryptoBox::decrypt(crypbobxInput,getEncodeKey(applicationLocation)));
|
||||
loadFromString(Botan::CryptoBox::decrypt(crypbobxInput, getEncodeKey(applicationLocation))); // does the result of this operation matter at all? Is it supposed to throw if the input is wrong? wtf?
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
//loaded string from application settings is invalid
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string License::getEncodeKey(const std::string applicationLocation) const
|
||||
{
|
||||
if (applicationLocation.size() <= 0)
|
||||
{
|
||||
std::cout << "No application location given" << std::endl;
|
||||
return "";
|
||||
}
|
||||
|
||||
Botan::PBKDF *pbkdf = Botan::get_pbkdf("PBKDF2(SHA-256)");
|
||||
Botan::secure_vector<Botan::byte> salt = Botan::base64_decode("34zA54n60v4CxjY5n20k3J40c976n690", 32);
|
||||
Botan::AutoSeeded_RNG rng;
|
||||
|
||||
@@ -67,8 +67,8 @@ private:
|
||||
std::string m_version;
|
||||
std::string m_publicKeyFilename;
|
||||
std::shared_ptr<Botan::RSA_PublicKey> m_publicKey;
|
||||
std::vector<std::string> lines;
|
||||
std::shared_ptr<Botan::AutoSeeded_RNG> m_rng;
|
||||
std::vector<std::string> m_lines;
|
||||
std::shared_ptr<Botan::AutoSeeded_RNG> m_rng; // range?
|
||||
|
||||
const std::string KEY_FILEENDING = ".pem";
|
||||
const std::string BEGIN_LICENSE = "-----BEGIN LICENSE-----";
|
||||
|
||||
Reference in New Issue
Block a user