Rev

Rev 3349 | Details | Compare with Previous | Last modification | View Log | SVN | Bug Tracker

Rev Author Line No. Line
3342 garciay 1
/*!
2
 * \file      security_cache.cc
3
 * \brief     Source file for a certificates caching storage mechanism.
4
 *            It is used to store certificates received from neighbors and not present in the data base
5
 * \author    ETSI STF525
6
 * \copyright ETSI Copyright Notification
7
 *            No part may be reproduced except as authorized by written permission.
8
 *            The copyright and the foregoing restriction extend to reproduction in all media.
9
 *            All rights reserved.
10
 * \version   0.1
11
 */
3343 garciay 12
#include <TTCN3.hh>
13
 
3227 filatov 14
#include "security_cache.hh"
15
 
16
#include "params.hh"
17
 
18
#include "converter.hh"
19
 
20
using namespace std; // Required for isnan()
21
#include "etsi_ts103097_certificate_codec.hh"
22
 
23
#include "loggers.hh"
24
 
3350 garciay 25
bool security_cache_comp::operator()(const OCTETSTRING& p_lhs, const OCTETSTRING& p_rhs) const {
3349 garciay 26
  loggers::get_instance().log_msg(">>> security_cache_comp::operator(): ", p_lhs);
27
  loggers::get_instance().log_msg(">>> security_cache_comp::operator(): ", p_rhs);
3350 garciay 28
  unsigned char* first1 = (unsigned char*)static_cast<const unsigned char*>(p_lhs);
29
  unsigned char* first2 = (unsigned char*)static_cast<const unsigned char*>(p_rhs);
30
  unsigned char* last1 = p_lhs.lengthof() + (unsigned char*)static_cast<const unsigned char*>(p_lhs);
31
  unsigned char* last2 = p_rhs.lengthof() + (unsigned char*)static_cast<const unsigned char*>(p_rhs);
32
 
33
  while (first1 != last1) {
34
    if ((first2 == last2) || (*first2 < *first1)) {
35
      return false;
36
    } else if (*first1 < *first2) {
37
      return true;
3349 garciay 38
    }
3350 garciay 39
    ++first1;
40
    ++first2;
41
  } // End of 'while' statement
42
  return (first2 != last2);
43
}
3349 garciay 44
 
3227 filatov 45
security_cache::security_cache(): _certificates(), _hashed_id8s() {
46
  loggers::get_instance().log(">>> security_cache::security_cache");
47
} // End of ctor
48
 
49
security_cache::~security_cache() {
50
  loggers::get_instance().log(">>> security_cache::~security_cache");
51
  clear();
52
} // End of dtor
53
 
54
int security_cache::clear() {
55
  loggers::get_instance().log(">>> security_cache::clear");
56
  _certificates.clear(); // Smart pointers will do the job
57
  _hashed_id8s.clear();
58
 
59
  return 0;
60
} // End of clear method
61
 
62
int security_cache::get_certificate_id(const OCTETSTRING& p_hashed_id8, std::string& p_certifcate_id) const {
63
  loggers::get_instance().log_msg(">>> security_cache::get_certificate_id: ", p_hashed_id8);
64
 
3350 garciay 65
  std::map<OCTETSTRING, std::string>::const_iterator it = _hashed_id8s.find(p_hashed_id8);
66
  //std::vector<unsigned char> v(static_cast<const unsigned char*>(p_hashed_id8), p_hashed_id8.lengthof() + static_cast<const unsigned char*>(p_hashed_id8));
67
  //std::map<std::vector<unsigned char>, std::string>::const_iterator it = _hashed_id8s.find(v);
3227 filatov 68
  if (it == _hashed_id8s.cend()) {
3349 garciay 69
    dump();
3227 filatov 70
    p_certifcate_id = "";
71
    return -1;
72
  }
73
  p_certifcate_id = it->second;
74
 
75
  return 0;
76
}
77
 
78
int security_cache::get_certificate(const std::string& p_certificate_id, OCTETSTRING& p_certificate) const {
79
  loggers::get_instance().log(">>> security_cache::get_certificate: '%s'", p_certificate_id.c_str());
80
 
81
  std::map<std::string, std::unique_ptr<security_db_record> >::const_iterator it = _certificates.find(p_certificate_id);
82
  if (it == _certificates.cend()) {
83
    loggers::get_instance().warning("security_cache::get_certificate: record not found");
84
    dump();
85
    return -1;
86
  }
3343 garciay 87
  p_certificate = it->second.get()->certificate();
3227 filatov 88
 
89
  return 0;
90
}
91
 
92
int security_cache::get_certificate(const std::string& p_certificate_id, IEEE1609dot2::CertificateBase& p_certificate) const {
93
  loggers::get_instance().log(">>> security_cache::get_certificate: '%s'", p_certificate_id.c_str());
94
 
95
  std::map<std::string, std::unique_ptr<security_db_record> >::const_iterator it = _certificates.find(p_certificate_id);
96
  if (it == _certificates.cend()) {
97
    loggers::get_instance().warning("security_cache::get_certificate: record not found");
98
    return -1;
99
  }
100
  p_certificate = it->second.get()->decoded_certificate();
101
 
102
  return 0;
103
}
104
 
105
int security_cache::get_issuer(const std::string& p_certificate_id, OCTETSTRING& p_hashed_id_issuer) const {
106
  loggers::get_instance().log(">>> security_cache::get_issuer: '%s'", p_certificate_id.c_str());
107
 
108
  std::map<std::string, std::unique_ptr<security_db_record> >::const_iterator it = _certificates.find(p_certificate_id);
109
  if (it == _certificates.cend()) {
110
    loggers::get_instance().warning("security_cache::get_issuer: record not found");
111
    return -1;
112
  }
3342 garciay 113
  p_hashed_id_issuer = it->second.get()->issuer();
3227 filatov 114
 
115
  return 0;
116
}
117
 
118
int security_cache::get_hashed_id(const std::string& p_certificate_id, OCTETSTRING& p_hashed_id) const {
119
  loggers::get_instance().log(">>> security_cache::get_hashed_id: '%s'", p_certificate_id.c_str());
120
 
121
  std::map<std::string, std::unique_ptr<security_db_record> >::const_iterator it = _certificates.find(p_certificate_id);
122
  if (it == _certificates.cend()) {
123
    loggers::get_instance().warning("security_cache::get_hashed_id: record not found");
124
    return -1;
125
  }
3342 garciay 126
  p_hashed_id = it->second.get()->hashed_id();
3227 filatov 127
 
128
  return 0;
129
}
130
 
131
int security_cache::get_hash(const std::string& p_certificate_id, OCTETSTRING& p_hash) const {
132
  loggers::get_instance().log(">>> security_cache::get_hash: '%s'", p_certificate_id.c_str());
133
 
134
  std::map<std::string, std::unique_ptr<security_db_record> >::const_iterator it = _certificates.find(p_certificate_id);
135
  if (it == _certificates.cend()) {
136
    loggers::get_instance().warning("security_cache::get_hash: record not found");
137
    return -1;
138
  }
3342 garciay 139
  p_hash = it->second.get()->hash();
3227 filatov 140
 
141
  return 0;
142
}
143
 
144
int security_cache::get_private_key(const std::string& p_certificate_id, OCTETSTRING& p_private_key) const {
145
  loggers::get_instance().log(">>> security_cache::get_private_key: '%s'", p_certificate_id.c_str());
146
 
147
  std::map<std::string, std::unique_ptr<security_db_record> >::const_iterator it = _certificates.find(p_certificate_id);
148
  if (it == _certificates.cend()) {
149
    loggers::get_instance().warning("security_cache::get_private_key: record not found");
150
    return -1;
151
  }
3342 garciay 152
  p_private_key = it->second.get()->private_key();
3227 filatov 153
 
154
  return 0;
155
}
156
 
157
int security_cache::get_public_keys(const std::string& p_certificate_id, OCTETSTRING& p_public_key_x, OCTETSTRING& p_public_key_y) const {
158
  loggers::get_instance().log(">>> security_cache::get_public_keys: '%s'", p_certificate_id.c_str());
159
 
160
  std::map<std::string, std::unique_ptr<security_db_record> >::const_iterator it = _certificates.find(p_certificate_id);
161
  if (it == _certificates.cend()) {
162
    loggers::get_instance().warning("security_cache::get_public_keys: record not found");
163
    return -1;
164
  }
3342 garciay 165
  p_public_key_x = it->second.get()->public_key_x();
166
  p_public_key_y = it->second.get()->public_key_y();
3227 filatov 167
 
168
  return 0;
169
}
170
 
171
int security_cache::get_public_comp_key(const std::string& p_certificate_id, OCTETSTRING& p_public_comp_key, INTEGER& p_comp_mode) const {
172
  loggers::get_instance().log(">>> security_cache::get_public_comp_key: '%s'", p_certificate_id.c_str());
173
 
174
  std::map<std::string, std::unique_ptr<security_db_record> >::const_iterator it = _certificates.find(p_certificate_id);
175
  if (it == _certificates.cend()) {
176
    loggers::get_instance().warning("security_cache::get_public_comp_key: record not found");
177
    return -1;
178
  }
3342 garciay 179
  const OCTETSTRING public_comp_key = it->second.get()->public_comp_key(); // 33 or 49 bytes length
3343 garciay 180
  p_public_comp_key = OCTETSTRING(public_comp_key.lengthof() - 1, 1 + static_cast<const unsigned char*>(public_comp_key)); // 32 or 48 bytes length
181
  p_comp_mode = INTEGER(((public_comp_key[0].get_octet() % 2) == 0) ? 0 : 1); // compressed-y-0 or compressed-y-1
3227 filatov 182
 
183
  return 0;
184
}
185
 
186
int security_cache::get_private_enc_key(const std::string& p_certificate_id, OCTETSTRING& p_private_enc_key) const {
187
  loggers::get_instance().log(">>> security_cache::get_private_enc_key: '%s'", p_certificate_id.c_str());
188
 
189
  std::map<std::string, std::unique_ptr<security_db_record> >::const_iterator it = _certificates.find(p_certificate_id);
190
  if (it == _certificates.cend()) {
191
    loggers::get_instance().warning("security_cache::get_private_enc_key: record not found");
192
    return -1;
193
  }
3343 garciay 194
  p_private_enc_key = it->second.get()->private_enc_key();
3227 filatov 195
 
196
  return 0;
197
}
198
 
199
int security_cache::get_public_enc_keys(const std::string& p_certificate_id, OCTETSTRING& p_public_enc_key_x, OCTETSTRING& p_public_enc_key_y) const {
200
  loggers::get_instance().log(">>> security_cache::get_public_enc_keys: '%s'", p_certificate_id.c_str());
201
 
202
  std::map<std::string, std::unique_ptr<security_db_record> >::const_iterator it = _certificates.find(p_certificate_id);
203
  if (it == _certificates.cend()) {
204
    loggers::get_instance().warning("security_cache::get_public_enc_keys: record not found");
205
    return -1;
206
  }
3343 garciay 207
  p_public_enc_key_x = it->second.get()->public_enc_key_x();
208
  p_public_enc_key_y = it->second.get()->public_enc_key_y();
3227 filatov 209
 
210
  return 0;
211
}
212
 
3256 garciay 213
int security_cache::get_public_enc_comp_key(const std::string& p_certificate_id, OCTETSTRING& p_public_enc_comp_key, INTEGER& p_enc_comp_mode) const {
214
  loggers::get_instance().log(">>> security_cache::get_public_enc_comp_key: '%s'", p_certificate_id.c_str());
215
 
216
  std::map<std::string, std::unique_ptr<security_db_record> >::const_iterator it = _certificates.find(p_certificate_id);
217
  if (it == _certificates.cend()) {
218
    loggers::get_instance().warning("security_cache::get_public_enc_comp_key: record not found");
219
    return -1;
220
  }
3342 garciay 221
  const OCTETSTRING public_enc_comp_key = it->second.get()->public_enc_comp_key(); // 33 or 49 bytes length
3343 garciay 222
  p_public_enc_comp_key = OCTETSTRING(public_enc_comp_key.lengthof() - 1, 1 + static_cast<const unsigned char*>(public_enc_comp_key)); // 32 or 48 bytes length
223
  p_enc_comp_mode = INTEGER(((public_enc_comp_key[0].get_octet() % 2) == 0) ? 0 : 1); // compressed-y-0 or compressed-y-1 
3256 garciay 224
 
225
  return 0;
226
}
227
 
3342 garciay 228
bool security_cache::fill_vector(OCTETSTRING& p_vector, const OCTETSTRING& p_org) {
3346 garciay 229
  if (p_org.is_bound()) {
3343 garciay 230
    p_vector = p_org;
3334 filatov 231
    return true;
232
  }
3342 garciay 233
  p_vector = OCTETSTRING(0, nullptr);
234
  return false;
3334 filatov 235
}
236
 
3347 garciay 237
int security_cache::store_certificate(const CHARSTRING& p_cert_id, const OCTETSTRING& p_cert, const OCTETSTRING& p_private_key, const OCTETSTRING& p_public_key_x, const OCTETSTRING& p_public_key_y, const OCTETSTRING& p_public_compressed_key, const INTEGER& p_public_compressed_key_mode, const OCTETSTRING& p_hash, const OCTETSTRING& p_hashed_id8, const OCTETSTRING& p_issuer, const OCTETSTRING& p_private_enc_key, const OCTETSTRING& p_public_enc_key_x, const OCTETSTRING& p_public_enc_key_y, const OCTETSTRING& p_public_enc_compressed_key, const INTEGER& p_public_enc_compressed_key_mode) {
3227 filatov 238
  loggers::get_instance().log_msg(">>> security_cache::store_certificate: ", p_cert_id);
239
 
240
  std::string key(static_cast<const char*>(p_cert_id));
3347 garciay 241
  OCTETSTRING cert, private_key, public_key_x, public_key_y, public_comp_key, hash, hashed_id8, issuer;
3342 garciay 242
  OCTETSTRING private_enc_key, public_enc_key_x, public_enc_key_y, public_enc_comp_key;
3227 filatov 243
 
3342 garciay 244
  security_cache::fill_vector(cert, p_cert);
245
  security_cache::fill_vector(private_key, p_private_key);
3334 filatov 246
 
3342 garciay 247
  security_cache::fill_vector(public_key_x, p_public_key_x);
248
  security_cache::fill_vector(public_key_y, p_public_key_y);
249
  if(fill_vector(public_comp_key, p_public_compressed_key)) {
250
    public_comp_key = int2oct((unsigned char)(2 + p_public_compressed_key_mode), 1) + public_comp_key; // Add one byte to indicate cmpressed-y-0 (0x02) or compressed-y-1 (0x03)
251
    loggers::get_instance().log_msg("security_cache::store_certificate: public_comp_key: ", public_comp_key);
3334 filatov 252
  }
253
 
3347 garciay 254
  security_cache::fill_vector(hash, p_hash);
3342 garciay 255
  security_cache::fill_vector(hashed_id8, p_hashed_id8);
256
  security_cache::fill_vector(issuer, p_issuer);
3337 garciay 257
 
3342 garciay 258
  security_cache::fill_vector(private_enc_key, p_private_enc_key);
259
  security_cache::fill_vector(public_enc_key_x, p_public_enc_key_x);
260
  security_cache::fill_vector(public_enc_key_y, p_public_enc_key_y);
3334 filatov 261
  if(fill_vector(public_enc_comp_key, p_public_enc_compressed_key)) {
3342 garciay 262
    public_enc_comp_key = int2oct((unsigned char)(2 + p_public_compressed_key_mode), 1) + public_enc_comp_key; // Add one byte to indicate cmpressed-y-0 (0x02) or compressed-y-1 (0x03)
263
    loggers::get_instance().log_msg("security_cache::store_certificate: public_enc_comp_key: ", public_enc_comp_key);
3334 filatov 264
  }
3227 filatov 265
 
266
  IEEE1609dot2::CertificateBase decoded_certificate;
267
  etsi_ts103097_certificate_codec codec;
268
  codec.decode(p_cert, decoded_certificate);
269
  loggers::get_instance().log_msg("security_cache::store_certificate: Decoded certificate: ", decoded_certificate);
270
  security_db_record* p = new security_db_record(
3256 garciay 271
                                                 key,                // Certificate id
272
                                                 cert,               // Certificate
3227 filatov 273
                                                 decoded_certificate,
3256 garciay 274
                                                 issuer,             // Hashed ID for the issuer
3347 garciay 275
                                                 hash,               // Whole-certificate hash
276
                                                 hashed_id8,         // Whole-certificate hashed ID
3256 garciay 277
                                                 private_key,        // Private key
278
                                                 public_key_x,       // Public key X-coordinate
279
                                                 public_key_y,       // Public key Y-coordinate
280
                                                 public_comp_key,    // Public compressed key, 33 or 49 bytes
281
                                                 private_enc_key,    // Private encryption key
282
                                                 public_enc_key_x,   // Public encryption key X-coordinate
283
                                                 public_enc_key_y,   // Public encryption key Y-coordinate
284
                                                 public_enc_comp_key // Public encryption compressed key, 33 or 49 bytes
3227 filatov 285
                                                 );
286
  if (p == nullptr) {
287
    return -1;
288
  }
289
  std::map<std::string, std::unique_ptr<security_db_record> >::const_iterator i = _certificates.find(key);
290
  if (i != _certificates.cend()) {
291
    _certificates.erase(i);
292
  }
3349 garciay 293
 
294
  _certificates.insert(std::pair<std::string, std::unique_ptr<security_db_record> >(key, std::unique_ptr<security_db_record>(p)));
295
 
3350 garciay 296
  std::map<OCTETSTRING, std::string>::const_iterator h = _hashed_id8s.find(hashed_id8);
297
  //std::vector<unsigned char> v(static_cast<const unsigned char*>(hashed_id8), hashed_id8.lengthof() + static_cast<const unsigned char*>(hashed_id8));
298
  //std::map<std::vector<unsigned char>, std::string>::const_iterator h = _hashed_id8s.find(v);
3227 filatov 299
  if (h != _hashed_id8s.cend()) {
300
    _hashed_id8s.erase(h);
301
  }
3350 garciay 302
  _hashed_id8s.insert(std::pair<OCTETSTRING, std::string&>(hashed_id8, key));
303
  //_hashed_id8s.insert(std::pair<std::vector<unsigned char>, std::string&>(v, key));
3349 garciay 304
 
3337 garciay 305
  //dump();
3227 filatov 306
 
307
  return 0;
308
}
309
 
310
void security_cache::dump() const {
3343 garciay 311
  loggers::get_instance().log("security_cache::dump_certificates: # items = %d", _certificates.size());
3227 filatov 312
  for (std::map<std::string, std::unique_ptr<security_db_record> >::const_iterator it = _certificates.cbegin(); it != _certificates.cend(); ++it) {
313
    security_db_record* p = it->second.get();
314
    loggers::get_instance().log("security_cache::dump: certificate_id = %s", p->certificate_id().c_str());
3342 garciay 315
    loggers::get_instance().log_msg("security_cache::dump: certificate = ", p->certificate());
3227 filatov 316
    loggers::get_instance().log_msg("security_cache::dump: decoded certificate = ", p->decoded_certificate());
3342 garciay 317
    loggers::get_instance().log_msg("security_cache::dump: issuer = ", p->issuer());
318
    loggers::get_instance().log_msg("security_cache::dump: hashed_id = ", p->hashed_id());
319
    loggers::get_instance().log_msg("security_cache::dump: hash = ", p->hash());
320
    loggers::get_instance().log_msg("security_cache::dump: private_key = ", p->private_key());
321
    loggers::get_instance().log_msg("security_cache::dump: public_key_x = ", p->public_key_x());
322
    loggers::get_instance().log_msg("security_cache::dump: public_key_y = ", p->public_key_y());
323
    loggers::get_instance().log_msg("security_cache::dump: public_comp_key = ", p->public_comp_key());
324
    loggers::get_instance().log_msg("security_cache::dump: private_enc_key = ", p->private_enc_key());
325
    loggers::get_instance().log_msg("security_cache::dump: public_enc_key_x = ", p->public_enc_key_x());
326
    loggers::get_instance().log_msg("security_cache::dump: public_enc_key_y = ", p->public_enc_key_y());
327
    loggers::get_instance().log_msg("security_cache::dump: public_enc_comp_key = ", p->public_enc_comp_key());
3227 filatov 328
  } // End of 'for' statement
3349 garciay 329
  //for (std::map<OCTETSTRING, std::string>::const_iterator it = _hashed_id8s.cbegin(); it != _hashed_id8s.cend(); ++it) {
3350 garciay 330
  for (std::map<OCTETSTRING/*std::vector<unsigned char>*/, std::string>::const_iterator it = _hashed_id8s.cbegin(); it != _hashed_id8s.cend(); ++it) {
331
    loggers::get_instance().log_msg("security_cache::dump: Hashedid8 key = ", it->first);
3349 garciay 332
    loggers::get_instance().log("security_cache::dump: Hashedid8 idx ==> %s", it->second.c_str());
3227 filatov 333
  } // End of 'for' statement
334
} // End of method dump