security_services.cc 20.4 KB
Newer Older
garciay's avatar
garciay committed
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
#include <chrono>

#include <openssl/ec.h>
#include <openssl/ecdsa.h>

#include "security_services.hh"

#include "EtsiTs103097Codec_ToBeSignedData.hh"
#include "EtsiTs103097Codec_Data.hh"

#include "sha256.hh"
#include "sha384.hh"
#include "ec_keys.hh"

#include "Params.hh"

#include "loggers.hh"

#include "converter.hh"

security_services * security_services::instance = NULL;

security_services::security_services() : _ec_keys(nullptr), _security_db(nullptr) {
  loggers::get_instance().log(">>> security_services::security_services");
} // End of ctor

int security_services::setup(Params& p_params) {
  loggers::get_instance().log("security_services::setup");
  p_params.log();

  _security_db.reset(new security_db(p_params[Params::sec_db_path]));
  if (_security_db.get() == nullptr) { // Memory allocation issue
    return -1;
  }
  
  return 0;
}

int security_services::verify_and_extract_gn_payload(const OCTETSTRING& p_secured_gn_payload, const bool p_verify, OCTETSTRING& p_unsecured_gn_payload, Params& p_params) {
  loggers::get_instance().log_msg(">>> security_services::verify_and_extract_gn_payload: ", p_secured_gn_payload);

  // Sanity checks
  if (p_secured_gn_payload.lengthof() == 0) {
    return -1;
  }
  
  // Decode the secured message (OER encoding)
  IEEE1609dot2::Ieee1609Dot2Data ieee_1609dot2_data;
  EtsiTs103097Codec_Data codec;
  codec.decode(p_secured_gn_payload, ieee_1609dot2_data, &p_params);
garciay's avatar
garciay committed
51
  // Sanity checks
garciay's avatar
garciay committed
52
  if (!ieee_1609dot2_data.is_bound()) {
garciay's avatar
garciay committed
53
    loggers::get_instance().warning("security_services::verify_and_extract_gn_payload: Unbound value, discard it");
garciay's avatar
garciay committed
54
55
56
    return -1;
  }
  if (p_verify && ((unsigned int)(int)ieee_1609dot2_data.protocolVersion() != security_services::ProtocolVersion)) {
garciay's avatar
garciay committed
57
58
    loggers::get_instance().warning("security_services::verify_and_extract_gn_payload: Wrong version protocol, discard it");
    return -1;
garciay's avatar
garciay committed
59
60
  }

garciay's avatar
garciay committed
61
  return process_ieee_1609_dot2_content(ieee_1609dot2_data.content(), p_verify, p_unsecured_gn_payload, p_params);
garciay's avatar
garciay committed
62
63
} // End of method verify_and_extract_gn_payload

garciay's avatar
garciay committed
64
65
int security_services::process_ieee_1609_dot2_content(const IEEE1609dot2::Ieee1609Dot2Content& p_ieee_1609_dot2_content, const bool p_verify, OCTETSTRING& p_unsecured_payload, Params& p_params) {
  loggers::get_instance().log_msg(">>> security_services::process_ieee_1609_dot2_content: ", p_ieee_1609_dot2_content);
garciay's avatar
garciay committed
66
  
garciay's avatar
garciay committed
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
  if (p_ieee_1609_dot2_content.ischosen(IEEE1609dot2::Ieee1609Dot2Content::ALT_unsecuredData)) { // Unsecured packet, End of recursivity
    p_unsecured_payload = p_ieee_1609_dot2_content.unsecuredData();
  } else if (p_ieee_1609_dot2_content.ischosen(IEEE1609dot2::Ieee1609Dot2Content::ALT_signedData)) {
    const IEEE1609dot2::SignedData& signedData = p_ieee_1609_dot2_content.signedData();
    if (process_ieee_1609_dot2_signed_data(signedData, p_verify, p_unsecured_payload, p_params) != 0) {
      return -1;
    }
  } else if (p_ieee_1609_dot2_content.ischosen(IEEE1609dot2::Ieee1609Dot2Content::ALT_encryptedData)) {
    loggers::get_instance().warning("security_services::process_ieee_1609_dot2_content: Unsupported IEEE 1609.2 Content, discard it");
    return -1;
  } else if (p_ieee_1609_dot2_content.ischosen(IEEE1609dot2::Ieee1609Dot2Content::ALT_signedCertificateRequest)) {
    // TODO Set Certificate re-transmission flag and reset timer
    loggers::get_instance().error("security_services::process_ieee_1609_dot2_content: TODO Set Certificate re-transmission flag and reset timer");
    return 0;
  } else { // Shall never be reached
    loggers::get_instance().warning("security_services::process_ieee_1609_dot2_content: Undefined IEEE 1609.2 Content, discard it");
garciay's avatar
garciay committed
83
84
85
    return -1;
  }
  
garciay's avatar
garciay committed
86
87
88
89
90
91
92
93
94
95
96
97
98
99
  loggers::get_instance().log_msg("<<< security_services::process_ieee_1609_dot2_content: ", p_unsecured_payload);
  return 0;
} // End of method process_ieee_1609_dot2_content

int security_services::process_ieee_1609_dot2_signed_data(const IEEE1609dot2::SignedData& p_signed_data, const bool p_verify, OCTETSTRING& p_unsecured_payload, Params& p_params) {
  loggers::get_instance().log_msg(">>> security_services::process_ieee_1609_dot2_signed_data: ", p_signed_data);

  // Check and extract unsecured payload
  if (p_signed_data.tbsData().payload().data().is_present()) {
    // Check protocol version
    const OPTIONAL<IEEE1609dot2::Ieee1609Dot2Data>& v = dynamic_cast<const OPTIONAL<IEEE1609dot2::Ieee1609Dot2Data>& >(p_signed_data.tbsData().payload().data());
    loggers::get_instance().log_msg("security_services::process_ieee_1609_dot2_signed_data: SignedDataPayload.data = ", v);
    const IEEE1609dot2::Ieee1609Dot2Data& ieee_1609dot2_data = static_cast<const IEEE1609dot2::Ieee1609Dot2Data&>(*v.get_opt_value());
    if (p_verify && ((unsigned int)(int)ieee_1609dot2_data.protocolVersion() != security_services::ProtocolVersion)) {
100
      loggers::get_instance().warning("security_services::process_ieee_1609_dot2_signed_data: Wrong version protocol, discard it");
garciay's avatar
garciay committed
101
102
103
      return -1;
    }
    if (process_ieee_1609_dot2_content(ieee_1609dot2_data.content(), p_verify, p_unsecured_payload, p_params) != 0) {
104
      loggers::get_instance().warning("security_services::process_ieee_1609_dot2_signed_data: Failed to process SignedData, discard it");
garciay's avatar
garciay committed
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
      return -1;
    }
  } else if (p_signed_data.tbsData().payload().extDataHash().is_present()) {
    loggers::get_instance().warning("security_services::process_ieee_1609_dot2_signed_data: Unsupported extDataHash, discard it");
    return -1;
  } else { // Shall not be reached
    loggers::get_instance().warning("security_services::process_ieee_1609_dot2_signed_data: Unsupported SignedDataPayload, discard it");
    return -1;
  }

  // Encode the ToBeSignedData
  EtsiTs103097Codec_ToBeSignedData tbs_data_codec;
  OCTETSTRING os;
  tbs_data_codec.encode(p_signed_data.tbsData(), os);
  if (os.lengthof() == 0) {
    loggers::get_instance().warning("security_services::process_ieee_1609_dot2_signed_data: Failed to encode ToBeSignedData");
    return -1;
  }
  loggers::get_instance().log_msg("security_services::process_ieee_1609_dot2_signed_data: encoded tbs_data = ", os);
  // Calculate the hash according to the hashId
  OCTETSTRING hashed_data;
  int result = -1;
  if (p_signed_data.hashId() == IEEE1609dot2BaseTypes::HashAlgorithm::sha256) {
    result = hash_sha256(os, hashed_data);
  } else {
    result = hash_sha384(os, hashed_data);
  }
  loggers::get_instance().log_msg("security_services::process_ieee_1609_dot2_signed_data: hashed_data = ", hashed_data);
  if (result != 0) {
    loggers::get_instance().warning("security_services::process_ieee_1609_dot2_signed_data: Failed to create hash");
    return -1;
  }
  // Retrieve certificate identifier
  loggers::get_instance().log_msg("security_services::process_ieee_1609_dot2_signed_data: signer = ", p_signed_data.signer());
  if (p_signed_data.signer().ischosen(IEEE1609dot2::SignerIdentifier::ALT_digest)) {
    // TODO Retrieve the certificate identifier from digest
    loggers::get_instance().error("security_services::process_ieee_1609_dot2_signed_data: TODO Retrieve the certificate identifier from digest");
  } else if (p_signed_data.signer().ischosen(IEEE1609dot2::SignerIdentifier::ALT_certificate)) {
    loggers::get_instance().error("security_services::process_ieee_1609_dot2_signed_data: Unsupported SignerIdentifier");
    return -1;
  } else {
    loggers::get_instance().warning("security_services::process_ieee_1609_dot2_signed_data: Unsupported SignerIdentifier");
    return -1;
  }
  // Verify the signature of the ToBeSignedData
  loggers::get_instance().log_msg("security_services::process_ieee_1609_dot2_signed_data: signature = ", p_signed_data.signature__());
  result = -1;
  if (p_signed_data.signature__().ischosen(IEEE1609dot2BaseTypes::Signature::ALT_ecdsaNistP256Signature)) {
    result = verify_sign_ecdsa_nistp256(os, p_signed_data.signature__(), "", p_params);
  } else {
    // TODO
    loggers::get_instance().error("security_services::process_ieee_1609_dot2_content: TODO");
  }
  if (result != 0) {
    loggers::get_instance().warning("security_services::process_ieee_1609_dot2_signed_data: Failed to verify signature");
    return -1;
  }

  loggers::get_instance().log_msg("<<< security_services::process_ieee_1609_dot2_signed_data: ", p_unsecured_payload);
  return 0;
} // End of method process_ieee_1609_dot2_signed_data

int security_services::process_ieee_1609_dot2_encrypted_data(const IEEE1609dot2::EncryptedData& p_encrypted_data, const bool p_verify, OCTETSTRING& p_unsecured_payload, Params& p_params) {
  loggers::get_instance().log_msg(">>> security_services::process_ieee_1609_dot2_encrypted_data: ", p_encrypted_data);

  //loggers::get_instance().log_msg("<<< security_services::process_ieee_1609_dot2_encrypted_data: ", p_unsecured_payload);
garciay's avatar
garciay committed
171
  return -1;
garciay's avatar
garciay committed
172
} // End of method process_ieee_1609_dot2_encrypted_data
garciay's avatar
garciay committed
173
174

int security_services::secure_gn_payload(const OCTETSTRING& p_unsecured_gn_payload, const bool p_add_certificate, OCTETSTRING& p_secured_gn_payload, Params& p_params) {
garciay's avatar
garciay committed
175
176
  loggers::get_instance().log_msg(">>> security_services::secure_gn_payload: ", p_unsecured_gn_payload);
  //p_params.log();
garciay's avatar
garciay committed
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205

  // Set unsecured data
  IEEE1609dot2::Ieee1609Dot2Content unsecured_data_content;
  unsecured_data_content.unsecuredData() = p_unsecured_gn_payload;
  IEEE1609dot2::Ieee1609Dot2Data unsecured_data(ProtocolVersion, unsecured_data_content);
  // Set hash algorithm
  IEEE1609dot2BaseTypes::HashAlgorithm hashId(IEEE1609dot2BaseTypes::HashAlgorithm::sha256);
  if (p_params[Params::hash].compare("SHA-384") == 0) {
    hashId = IEEE1609dot2BaseTypes::HashAlgorithm::sha384;
  }
  // Set SignedDataPayload
  IEEE1609dot2::SignedDataPayload payload;
  payload.data() = unsecured_data;
  payload.extDataHash().set_to_omit();
  IEEE1609dot2::HeaderInfo header_info;
  header_info.psid() = converter::get_instance().string_to_int(p_params[Params::its_aid]);
  unsigned long long ms = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count() - 1072911600000L;  // TODO Add method such as its_tme() & its_time_mod() beacuse it is used also in LibItsCommon_externals
  header_info.generationTime() = ms;
  header_info.expiryTime().set_to_omit();
  header_info.generationLocation().set_to_omit();
  header_info.p2pcdLearningRequest().set_to_omit();
  header_info.missingCrlIdentifier().set_to_omit();
  header_info.encryptionKey().set_to_omit();
  header_info.inlineP2pcdRequest().set_to_omit();
  header_info.requestedCertificate().set_to_omit();

  IEEE1609dot2::ToBeSignedData tbs_data;
  tbs_data.payload() = payload;
  tbs_data.headerInfo() = header_info;
garciay's avatar
garciay committed
206
  loggers::get_instance().log_msg("security_services::secure_gn_payload: tbs_data = ", tbs_data);
garciay's avatar
garciay committed
207
208
209
  // Sign the ToBeSignedData data structure
  IEEE1609dot2BaseTypes::Signature signature;
  if (sign_tbs_data(tbs_data, hashId, signature, p_params) != 0) {
garciay's avatar
garciay committed
210
    loggers::get_instance().warning("security_services::secure_gn_payload: Failed to secure payload");
garciay's avatar
garciay committed
211
212
213
    return -1;
  }
  IEEE1609dot2::SignerIdentifier signer;
garciay's avatar
garciay committed
214
  std::string certificate_id = p_params[Params::certificate] + "_at";
garciay's avatar
garciay committed
215
  loggers::get_instance().log("security_services::secure_gn_payload: certificate_id = %s", certificate_id.c_str());
garciay's avatar
garciay committed
216
217
  if (!p_add_certificate) {
    OCTETSTRING digest;
garciay's avatar
garciay committed
218
    if (_security_db->get_hashed_id(certificate_id, digest) != 0) {
garciay's avatar
garciay committed
219
      loggers::get_instance().warning("security_services::secure_gn_payload: Failed to secure payload");
garciay's avatar
garciay committed
220
221
222
    return -1;
    }
    signer.digest() = digest;
garciay's avatar
garciay committed
223
  } else {
garciay's avatar
garciay committed
224
    OCTETSTRING cert;
garciay's avatar
garciay committed
225
    if (_security_db->get_certificate(certificate_id, cert) != 0) {
garciay's avatar
garciay committed
226
      loggers::get_instance().warning("security_services:secure_gn_payload: Failed to secure payload");
garciay's avatar
garciay committed
227
228
      return -1;
    }
garciay's avatar
garciay committed
229
    loggers::get_instance().error("security_services::process_ieee_1609_dot2_content: TODO Add certifcate case");
garciay's avatar
garciay committed
230
231
232
233
234
235
236
237
    // FIXME Need to decode certifcate, shall be done once is security_db
  }
  IEEE1609dot2::SignedData signed_data(
                                       hashId,
                                       tbs_data,
                                       signer,
                                       signature
                                       );
garciay's avatar
garciay committed
238
  loggers::get_instance().log_msg("security_services::secure_gn_payload: signed_data = ", signed_data);
garciay's avatar
garciay committed
239
240
241
242
243
244
  IEEE1609dot2::Ieee1609Dot2Content ieee_dot2_content;
  ieee_dot2_content.signedData() = signed_data;
  IEEE1609dot2::Ieee1609Dot2Data ieee_1609dot2_data(
                                                    security_services::ProtocolVersion,
                                                    ieee_dot2_content
                                                    );
garciay's avatar
garciay committed
245
  loggers::get_instance().log_msg("security_services::secure_gn_payload: ieee_1609dot2_data = ", ieee_1609dot2_data);
garciay's avatar
garciay committed
246
247
248
  EtsiTs103097Codec_Data codec;
  codec.encode(ieee_1609dot2_data, p_secured_gn_payload);
  if (!p_secured_gn_payload.is_bound()) {
garciay's avatar
garciay committed
249
    loggers::get_instance().warning("security_services::secure_gn_payload: Failed to encode Ieee1609Dot2Data");
garciay's avatar
garciay committed
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
    return -1;
  }
  
  return 0;
}

int security_services::sign_tbs_data(const IEEE1609dot2::ToBeSignedData& p_tbs_data, const IEEE1609dot2BaseTypes::HashAlgorithm& p_hashAlgorithm, IEEE1609dot2BaseTypes::Signature& p_signature, Params& p_params) {
  loggers::get_instance().log_msg(">>> security_services::sign_tbs_data: ", p_tbs_data);
  
  // Encode the ToBeSignedData
  EtsiTs103097Codec_ToBeSignedData tbs_data_codec;
  OCTETSTRING os;
  tbs_data_codec.encode(p_tbs_data, os);
  if (os.lengthof() == 0) {
    loggers::get_instance().warning("security_services::sign_tbs_data: Failed to encode ToBeSignedData");
    return -1;
  }
  loggers::get_instance().log_msg("security_services::sign_tbs_data: encoded tbs_data = ", os);
  // Hash ToBeSignedData
  OCTETSTRING hashed_data;
  int result = -1;
  if (p_hashAlgorithm == IEEE1609dot2BaseTypes::HashAlgorithm::sha256) {
    result = hash_sha256(os, hashed_data);
  } else {
    result = hash_sha384(os, hashed_data);
  }
  loggers::get_instance().log_msg("security_services::sign_tbs_data: encoded hashed_data = ", hashed_data);
  if (result != 0) {
    loggers::get_instance().warning("security_services::sign_tbs_data: Failed to create hash");
    return -1;
  }
  // Sign ToBeSignedData
  result = -1;
  loggers::get_instance().log("security_services::sign_tbs_data: encoded Params::signature = '%s'", p_params[Params::signature].c_str());
  loggers::get_instance().log("security_services::sign_tbs_data: encoded Params::certificate = '%s'", p_params[Params::certificate].c_str());
  if (p_params[Params::signature].compare("NISTP-256") == 0) {
    result = sign_ecdsa_nistp256(hashed_data, p_signature, p_params);
garciay's avatar
garciay committed
287
288
289
290
291
  } else {
    // TODO Add other signature algorithm
    loggers::get_instance().error("security_services::process_ieee_1609_dot2_content: TODO Add other signature algorithm");
    result = -1;
  }
garciay's avatar
garciay committed
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
  if (result != 0) {
    loggers::get_instance().warning("security_services::sign_tbs_data: Failed to sign payload");
    return -1;
  }
  
  return 0;
}

int security_services::hash_sha256(const OCTETSTRING& p_data, OCTETSTRING& p_hash_data) {
  loggers::get_instance().log_msg(">>> security_services::hash_sha256: ", p_data);
  
  sha256 hash;
  std::vector<unsigned char> tbh(static_cast<const unsigned char *>(p_data), p_data.lengthof() + static_cast<const unsigned char *>(p_data));
  std::vector<unsigned char> hashData;
  hash.generate(tbh, hashData);
  p_hash_data = OCTETSTRING(hashData.size(), hashData.data());

  return 0;
}

int security_services::hash_sha384(const OCTETSTRING& p_data, OCTETSTRING& p_hash_data) {
  loggers::get_instance().log_msg(">>> security_services::hash_sha384: ", p_data);
  
  sha384 hash;
  std::vector<unsigned char> tbh(static_cast<const unsigned char *>(p_data), p_data.lengthof() + static_cast<const unsigned char *>(p_data));
  std::vector<unsigned char> hashData;
  hash.generate(tbh, hashData);
  p_hash_data = OCTETSTRING(hashData.size(), hashData.data());
  
  return 0;
}

int security_services::sign_ecdsa_nistp256(const OCTETSTRING& p_hash, IEEE1609dot2BaseTypes::Signature& p_signature, Params& p_params) {
  loggers::get_instance().log_msg(">>> security_services::sign_ecdsa_nistp256: ", p_hash);
  
garciay's avatar
garciay committed
327
328
  std::string certificate_id = p_params[Params::certificate] + "_at";
  loggers::get_instance().log("security_services::sign_tbs_data: encoded certificate_id = '%s'", certificate_id.c_str());
garciay's avatar
garciay committed
329
  OCTETSTRING pkey;
garciay's avatar
garciay committed
330
  if (_security_db->get_private_key(certificate_id, pkey) != 0) {
garciay's avatar
garciay committed
331
332
333
334
335
336
    loggers::get_instance().warning("security_services::sign_ecdsa_nistp256: Failed to get private key");
    return -1;
  }
  std::vector<unsigned char> private_key(static_cast<const unsigned char *>(pkey), static_cast<const unsigned char *>(pkey) + pkey.lengthof());
  OCTETSTRING public_key_x;
  OCTETSTRING public_key_y;
garciay's avatar
garciay committed
337
  if (_security_db->get_public_keys(certificate_id, public_key_x, public_key_y) != 0) {
garciay's avatar
garciay committed
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
    loggers::get_instance().warning("security_services::sign_ecdsa_nistp256: Failed to get public keys");
    return -1;
  }
  
  std::vector<unsigned char> hashed_data(static_cast<const unsigned char *>(p_hash), static_cast<const unsigned char *>(p_hash) + p_hash.lengthof());
  ec_keys k(ec_elliptic_curves::nist_p_256, private_key);
  std::vector<unsigned char> r_sig;
  std::vector<unsigned char> s_sig;
  if (k.sign(hashed_data, r_sig, s_sig) != 0) {
    loggers::get_instance().warning("security_services::sign_ecdsa_nistp256: Failed to sign payload");
    return -1;
  }
  IEEE1609dot2BaseTypes::EccP256CurvePoint ep;
  ep.uncompressedP256() = IEEE1609dot2BaseTypes::EccP256CurvePoint_uncompressedP256(
                                                                                    public_key_x,
                                                                                    public_key_y
                                                                                    );
  p_signature.ecdsaNistP256Signature() = IEEE1609dot2BaseTypes::EcdsaP256Signature(
                                                                                   ep,
                                                                                   OCTETSTRING(r_sig.size(), r_sig.data()) + OCTETSTRING(s_sig.size(), s_sig.data())
                                                                                   );
  loggers::get_instance().log_msg("security_services::sign_ecdsa_nistp256: signature = ", p_signature);
  
  return 0;
}

garciay's avatar
garciay committed
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
int security_services::verify_sign_ecdsa_nistp256(const OCTETSTRING& p_hash, const IEEE1609dot2BaseTypes::Signature& p_signature, const std::string& p_certificate_id, Params& p_params) {
  loggers::get_instance().log_msg(">>> security_services::verify_sign_ecdsa_nistp256: ", p_hash);
  
  std::string certificate_id = p_params[Params::certificate] + "_at";
  loggers::get_instance().log("security_services::sign_tbs_data: encoded certificate_id = '%s'", certificate_id.c_str());
  OCTETSTRING public_key_x;
  OCTETSTRING public_key_y;
  if (_security_db->get_public_keys(certificate_id, public_key_x, public_key_y) != 0) {
    loggers::get_instance().warning("security_services::verify_sign_ecdsa_nistp256: Failed to get public keys");
    return -1;
  }
  // // Calculate the hash
  // sha256 hash;
  // std::vector<unsigned char> hashData;
  // // TODO Create SHX interface and add generate method with std::vector
  // std::vector<unsigned char> tbh(static_cast<const unsigned char *>(p__toBeVerifiedData), static_cast<const unsigned char *>(p__toBeVerifiedData) + p__toBeVerifiedData.lengthof());
  // hash.generate(tbh, hashData);
  // // Check the signature
  // std::vector<unsigned char> signature(static_cast<const unsigned char *>(p__signature), static_cast<const unsigned char *>(p__signature) + p__signature.lengthof());
  // std::vector<unsigned char> pub_key_x(static_cast<const unsigned char *>(p__ecdsaNistp256PublicKeyX), static_cast<const unsigned char *>(p__ecdsaNistp256PublicKeyX) + p__ecdsaNistp256PublicKeyX.lengthof());
  // std::vector<unsigned char> pub_key_y(static_cast<const unsigned char *>(p__ecdsaNistp256PublicKeyY), static_cast<const unsigned char *>(p__ecdsaNistp256PublicKeyY) + p__ecdsaNistp256PublicKeyY.lengthof());
  // ec_keys k(ec_elliptic_curves::nist_p_256, pub_key_x, pub_key_y);
  // if (k.sign_verif(hashData, signature) == 0) {
  //   return TRUE;
  // }
  
  return -1;
}