Gabriele Contini
2020-03-21 079123b5c4c25a453ba4d3c6ffa1b5f9f39c5dad
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
/*
 * hw_identifier.cpp
 *
 *  Created on: Dec 22, 2019
 *      Author: GC
 */
 
#include <algorithm>
#include "hw_identifier.hpp"
#include "../base/base64.h"
 
namespace license {
namespace hw_identifier {
 
using namespace std;
 
HwIdentifier::HwIdentifier() {}
 
HwIdentifier::HwIdentifier(const std::string& param) {
    string tmp_str(param);  // throw away const
    std::replace(tmp_str.begin(), tmp_str.end(), '-', '\n');
    vector<uint8_t> decoded = unbase64(tmp_str);
    if (decoded.size() != HW_IDENTIFIER_PROPRIETARY_DATA + 1) {
        cerr << decoded.size();
        throw logic_error("wrong identifier size " + param);
    }
    std::copy_n(decoded.begin(), HW_IDENTIFIER_PROPRIETARY_DATA + 1, m_data.begin());
}
 
HwIdentifier::~HwIdentifier() {}
 
HwIdentifier::HwIdentifier(const HwIdentifier& other) : m_data(other.m_data) {}
 
void HwIdentifier::set_identification_strategy(LCC_API_HW_IDENTIFICATION_STRATEGY strategy) {
    if (strategy == STRATEGY_NONE || strategy == STRATEGY_DEFAULT) {
        throw logic_error("Only known strategies are permitted");
    }
    uint8_t stratMov = (strategy << 5);
    m_data[1] = (m_data[1] & 0x1F) | stratMov;
}
 
void HwIdentifier::set_use_environment_var(bool use_env_var) {
    if (use_env_var) {
        m_data[0] = m_data[0] | 0x40;
    } else {
        m_data[0] = m_data[0] & ~0x40;
    }
}
 
void HwIdentifier::set_virtual_environment(os::VIRTUALIZATION virt) {
    // 110000 0x30
    m_data[0] = (m_data[0] & ~0x30) | virt << 4;
}
 
void HwIdentifier::set_virtualization(os::VIRTUALIZATION_DETAIL virtualization_detail) {
    m_data[0] = (m_data[0] & ~0x0F) | virtualization_detail;
}
 
void HwIdentifier::set_cloud_provider(os::CLOUD_PROVIDER cloud_provider) {
    m_data[0] = (m_data[0] & ~0x0F) | cloud_provider | 0x08;
}
 
void HwIdentifier::set_data(const std::array<uint8_t, HW_IDENTIFIER_PROPRIETARY_DATA>& data) {
    m_data[1] = (m_data[1] & (~0x1f)) | (data[0] & 0x1f);
    for (int i = 1; i < HW_IDENTIFIER_PROPRIETARY_DATA; i++) {
        m_data[i + 1] = data[i];
    }
}
 
std::string HwIdentifier::print() const {
    string result = base64(m_data.data(), m_data.size(), 5);
    std::replace(result.begin(), result.end(), '\n', '-');
    return result.substr(0, result.size() - 1);
}
 
LCC_API_HW_IDENTIFICATION_STRATEGY HwIdentifier::get_identification_strategy() const {
    uint8_t stratMov = m_data[1] >> 5;
    return static_cast<LCC_API_HW_IDENTIFICATION_STRATEGY>(stratMov);
}
 
bool HwIdentifier::data_match(const std::array<uint8_t, HW_IDENTIFIER_PROPRIETARY_DATA>& data) const {
    bool equals = true;
    for (int i = 0; i < HW_IDENTIFIER_PROPRIETARY_DATA && equals; i++) {
        equals = (i == 0) ? ((data[i] & 0x1f) == (m_data[i + 1] & 0x1f)) : (data[i] == m_data[i + 1]);
    }
    return equals;
}
 
bool operator==(const HwIdentifier& lhs, const HwIdentifier& rhs) {
    bool equals = lhs.get_identification_strategy() == rhs.get_identification_strategy();
    for (int i = 0; i < HW_IDENTIFIER_PROPRIETARY_DATA && equals; i++) {
        equals = (i == 0) ? ((rhs.m_data[i + 1] & 0x1f) == (lhs.m_data[i + 1] & 0x1f))
                          : (lhs.m_data[i + 1] == rhs.m_data[i + 1]);
    }
    return equals;
}
 
}  // namespace hw_identifier
} /* namespace license */