Cryptolens Client API for C++
basic_SKM.hpp
1 #pragma once
2 
3 #include <cstring>
4 #include <string>
5 #include <sstream>
6 #include <unordered_map>
7 
8 #include "imports/std/optional"
9 
10 #include "imports/ArduinoJson5/ArduinoJson.hpp"
11 
12 #include "ActivateError.hpp"
13 #include "basic_Error.hpp"
14 #include "RawLicenseKey.hpp"
15 #include "LicenseKey.hpp"
16 #include "LicenseKeyInformation.hpp"
17 #include "LicenseKeyChecker.hpp"
18 #include "api.hpp"
19 
20 namespace cryptolens_io {
21 
22 namespace v20180502 {
23 
24 namespace internal {
25 
26 template<typename SignatureVerifier>
27 optional<RawLicenseKey>
28 handle_activate
29  ( basic_Error & e
30  , SignatureVerifier const& signature_verifier
31  , std::string const& response
32  );
33 
34 } // namespace internal
35 
36 template<typename SignatureVerifier>
37 optional<RawLicenseKey>
38 handle_activate_raw
39  ( basic_Error & e
40  , SignatureVerifier const& signature_verifier
41  , std::string const& response
42  )
43 {
44  if (e) { return nullopt; }
45 
46  auto x = internal::handle_activate(e, signature_verifier, response);
47  if (e) { e.set_call(api::main(), errors::Call::BASIC_SKM_HANDLE_ACTIVATE_RAW); }
48  return x;
49 }
50 
51 template<typename SignatureVerifier>
52 RawLicenseKey
53 handle_activate_raw_exn
54  ( api::experimental_v1 experimental
55  , SignatureVerifier const& signature_verifier
56  , std::string const& response
57  )
58 {
59  basic_Error e;
60  optional<RawLicenseKey> raw_license_key =
61  handle_activate(e, signature_verifier, response);
62 
63  if (raw_license_key && !e) { return *raw_license_key; }
64 
65  throw ActivateError::from_server_response(NULL);
66 }
67 
68 template<typename SignatureVerifier>
69 optional<LicenseKey>
70 handle_activate
71  ( basic_Error & e
72  , SignatureVerifier const& signature_verifier
73  , std::string const& response
74  )
75 {
76  if (e) { return nullopt; }
77 
78  optional<RawLicenseKey> x = internal::handle_activate(e, signature_verifier, response);
79  optional<LicenseKeyInformation> y = LicenseKeyInformation::make(e, x);
80  if (e) { e.set_call(api::main(), errors::Call::BASIC_SKM_HANDLE_ACTIVATE); }
81 
82  return LicenseKey(std::move(*y), std::move(*x));
83 }
84 
96 template<typename RequestHandler, typename SignatureVerifier>
97 class basic_SKM
98 {
99 public:
100  basic_SKM() { }
101 
102  optional<LicenseKey>
103  activate
104  ( basic_Error & e
105  , std::string token
106  , std::string product_id
107  , std::string key
108  , std::string machine_code
109  , int fields_to_return = 0
110  );
111 
112  optional<RawLicenseKey>
113  activate_raw
114  ( basic_Error & e
115  , std::string token
116  , std::string product_id
117  , std::string key
118  , std::string machine_code
119  , int fields_to_return = 0
120  );
121 
122  optional<LicenseKey>
123  activate_floating
124  ( basic_Error & e
125  , std::string token
126  , std::string product_id
127  , std::string key
128  , std::string machine_code
129  , long floating_time_interval
130  , int fields_to_return = 0
131  );
132 
134  activate_raw_exn
135  ( api::experimental_v1 experimental
136  , std::string token
137  , std::string product_id
138  , std::string key
139  , std::string machine_code
140  , int fields_to_return = 0
141  );
142 
143  optional<LicenseKey>
144  make_license_key(basic_Error & e, std::string const& s);
145 
146  SignatureVerifier signature_verifier;
147  RequestHandler request_handler;
148 
149 private:
150  optional<RawLicenseKey>
151  activate_
152  ( basic_Error & e
153  , std::string token
154  , std::string product_id
155  , std::string key
156  , std::string machine_code
157  , int fields_to_return = 0
158  );
159 
160  optional<RawLicenseKey>
161  activate_floating_
162  ( basic_Error & e
163  , std::string token
164  , std::string product_id
165  , std::string key
166  , std::string machine_code
167  , long floating_time_interval
168  , int fields_to_return = 0
169  );
170 };
171 
186 template<typename RequestHandler, typename SignatureVerifier>
187 optional<LicenseKey>
190  , std::string token
191  , std::string product_id
192  , std::string key
193  , std::string machine_code
194  , int fields_to_return
195  )
196 {
197  if (e) { return nullopt; }
198 
199  optional<RawLicenseKey> x = this->activate_
200  ( e
201  , std::move(token)
202  , std::move(product_id)
203  , std::move(key)
204  , std::move(machine_code)
205  , fields_to_return
206  );
207  optional<LicenseKeyInformation> y = LicenseKeyInformation::make(e, x);
208  if (e) { e.set_call(api::main(), errors::Call::BASIC_SKM_ACTIVATE); return nullopt; }
209  return LicenseKey(std::move(*y), std::move(*x));
210 }
211 
226 template<typename RequestHandler, typename SignatureVerifier>
227 optional<RawLicenseKey>
230  , std::string token
231  , std::string product_id
232  , std::string key
233  , std::string machine_code
234  , int fields_to_return
235  )
236 {
237  if (e) { return nullopt; }
238 
239  auto x = this->activate_( e
240  , std::move(token)
241  , std::move(product_id)
242  , std::move(key)
243  , std::move(machine_code)
244  , fields_to_return
245  );
246  if (e) { e.set_call(api::main(), errors::Call::BASIC_SKM_ACTIVATE_RAW); }
247  return x;
248 }
249 
274 template<typename RequestHandler, typename SignatureVerifier>
275 optional<LicenseKey>
278  , std::string token
279  , std::string product_id
280  , std::string key
281  , std::string machine_code
282  , long floating_time_interval
283  , int fields_to_return
284  )
285 {
286  if (e) { return nullopt; }
287 
288  optional<RawLicenseKey> x = this->activate_floating_
289  ( e
290  , std::move(token)
291  , std::move(product_id)
292  , std::move(key)
293  , std::move(machine_code)
294  , floating_time_interval
295  , fields_to_return
296  );
297  optional<LicenseKeyInformation> y = LicenseKeyInformation::make(e, x);
298  if (e) { e.set_call(api::main(), errors::Call::BASIC_SKM_ACTIVATE_FLOATING); return nullopt; }
299  return LicenseKey(std::move(*y), std::move(*x));
300 }
301 
302 template<typename RequestHandler, typename SignatureVerifier>
303 optional<RawLicenseKey>
305  ( basic_Error & e
306  , std::string token
307  , std::string product_id
308  , std::string key
309  , std::string machine_code
310  , int fields_to_return
311  )
312 {
313  if (e) { return nullopt; }
314 
315  std::unordered_map<std::string,std::string> args;
316  args["token"] = token;
317  args["ProductId"] = product_id;
318  args["Key"] = key;
319  args["Sign"] = "true";
320  args["MachineCode"] = machine_code;
321  // Fix since to_string is not available everywhere
322  //args["FieldsToReturn"] = std::to_string(fields_to_return);
323  std::ostringstream stm; stm << fields_to_return;
324  args["FieldsToReturn"] = stm.str();
325  args["SignMethod"] = "1";
326  args["v"] = "1";
327 
328  std::string response = request_handler.make_request(e, "Activate", args);
329 
330  return ::cryptolens_io::v20180502::handle_activate_raw(e, this->signature_verifier, response);
331 }
332 
333 template<typename RequestHandler, typename SignatureVerifier>
334 optional<RawLicenseKey>
336  ( basic_Error & e
337  , std::string token
338  , std::string product_id
339  , std::string key
340  , std::string machine_code
341  , long floating_time_interval
342  , int fields_to_return
343  )
344 {
345  if (e) { return nullopt; }
346 
347  std::unordered_map<std::string,std::string> args;
348  args["token"] = token;
349  args["ProductId"] = product_id;
350  args["Key"] = key;
351  args["Sign"] = "true";
352  args["MachineCode"] = machine_code;
353  // Fix since to_string is not available everywhere
354  //args["FieldsToReturn"] = std::to_string(fields_to_return);
355  std::ostringstream stm; stm << fields_to_return;
356  args["FieldsToReturn"] = stm.str();
357  args["SignMethod"] = "1";
358  args["v"] = "1";
359  stm.str(""); stm.clear(); stm << floating_time_interval;
360  args["FloatingTimeInterval"] = stm.str();
361 
362  std::string response = request_handler.make_request(e, "Activate", args);
363 
364  return ::cryptolens_io::v20180502::handle_activate_raw(e, this->signature_verifier, response);
365 }
366 
380 template<typename RequestHandler, typename SignatureVerifier>
383  ( api::experimental_v1 experimental
384  , std::string token
385  , std::string product_id
386  , std::string key
387  , std::string machine_code
388  , int fields_to_return
389  )
390 {
391  basic_Error e;
392  optional<RawLicenseKey> raw_license_key =
393  activate_raw( e, std::move(token), std::move(product_id), std::move(key)
394  , std::move(machine_code), fields_to_return);
395 
396  if (!e) { return *raw_license_key; }
397  throw ActivateError::from_server_response(NULL);
398 }
399 
400 template<typename RequestHandler, typename SignatureVerifier>
401 optional<LicenseKey>
403 {
404  if (e) { return nullopt; }
405 
406  optional<RawLicenseKey> raw_license_key;
407 
408  raw_license_key =
409  ::cryptolens_io::v20180502::internal::handle_activate(e, this->signature_verifier, s);
410 
411  if (e) {
412  e.reset(api::main());
413 
414  size_t k = s.find('-');
415  if (k == std::string::npos) { e.set(api::main(), errors::Subsystem::Main, errors::Main::UNKNOWN_SERVER_REPLY); return nullopt; }
416 
417  std::string version = s.substr(0, k);
418  std::string rem = s.substr(k+1, std::string::npos);
419  // NOTE: s.substr(s.size(), _) returns empty string, thus the previous line does never throw
420 
421  k = rem.find('-');
422  if (k == std::string::npos) { e.set(api::main(), errors::Subsystem::Main, errors::Main::UNKNOWN_SERVER_REPLY); return nullopt; }
423 
424  std::string license = rem.substr(0, k);
425  std::string signature = rem.substr(k+1, std::string::npos); // k+1 is fine, see comment above
426 
427  raw_license_key =
428  RawLicenseKey::make
429  ( e
430  , signature_verifier
431  , license
432  , signature
433  );
434  }
435 
436  optional<LicenseKeyInformation> license_key_information = LicenseKeyInformation::make(e, raw_license_key);
437  if (e) { e.set_call(api::main(), errors::Call::BASIC_SKM_MAKE_LICENSE_KEY); return nullopt; }
438  return LicenseKey(std::move(*license_key_information), std::move(*raw_license_key));
439 }
440 
441 
442 namespace internal {
443 
444 int
445 activate_parse_server_error_message(char const* server_response);
446 
447 template<typename SignatureVerifier>
448 optional<RawLicenseKey>
449 handle_activate
450  ( basic_Error & e
451  , SignatureVerifier const& signature_verifier
452  , std::string const& response
453  )
454 {
455  if (e) { return nullopt; }
456 
457  using namespace errors;
458  api::main api;
459 
460  using namespace ArduinoJson;
461  DynamicJsonBuffer jsonBuffer;
462  JsonObject & j = jsonBuffer.parseObject(response);
463 
464  if (!j.success()) { e.set(api, Subsystem::Json); return nullopt; }
465 
466  if (!j["result"].is<int>() || j["result"].as<int>() != 0) {
467  if (!j["message"].is<const char*>() || j["message"].as<char const*>() == NULL) {
468  e.set(api, Subsystem::Main, Main::UNKNOWN_SERVER_REPLY);
469  return nullopt;
470  }
471 
472  int reason = activate_parse_server_error_message(j["message"].as<char const*>());
473  e.set(api, Subsystem::Main, reason);
474  return nullopt;
475  }
476 
477  if (!j["licenseKey"].is<char const*>() || j["licenseKey"].as<char const*>() == NULL) {
478  e.set(api, Subsystem::Main, Main::UNKNOWN_SERVER_REPLY);
479  return nullopt;
480  }
481 
482  if (!j["signature"].is<char const*>() || j["signature"].as<char const*>() == NULL) {
483  e.set(api, Subsystem::Main, Main::UNKNOWN_SERVER_REPLY);
484  return nullopt;
485  }
486 
487  return RawLicenseKey::make
488  ( e
489  , signature_verifier
490  , j["licenseKey"].as<char const*>()
491  , j["signature"].as<char const*>()
492  );
493 }
494 
495 } // namespace internal
496 
497 } // namespace v20180502
498 
499 } // namespace cryptolens_io
optional< RawLicenseKey > activate_raw(basic_Error &e, std::string token, std::string product_id, std::string key, std::string machine_code, int fields_to_return=0)
Definition: basic_SKM.hpp:229
static optional< LicenseKeyInformation > make(basic_Error &e, RawLicenseKey const &raw_license_key)
Definition: LicenseKeyInformation.cpp:73
Definition: basic_SKM.hpp:97
virtual void reset(api::main api)
Definition: basic_Error.hpp:119
RawLicenseKey activate_raw_exn(api::experimental_v1 experimental, std::string token, std::string product_id, std::string key, std::string machine_code, int fields_to_return=0)
Definition: basic_SKM.hpp:383
Definition: ActivateError.hpp:5
optional< LicenseKey > activate(basic_Error &e, std::string token, std::string product_id, std::string key, std::string machine_code, int fields_to_return=0)
Definition: basic_SKM.hpp:189
optional< LicenseKey > activate_floating(basic_Error &e, std::string token, std::string product_id, std::string key, std::string machine_code, long floating_time_interval, int fields_to_return=0)
Definition: basic_SKM.hpp:277
Definition: RawLicenseKey.hpp:24
Definition: basic_Error.hpp:90
Definition: LicenseKey.hpp:34