Commit 253ec340 authored by garciay's avatar garciay
Browse files

Validation of TD_AUTO_IOT_DENM_SVW_BV_01 done

parent 0ec9a035
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -173,8 +173,14 @@ void GeoNetworkingLayer::receiveData(OCTETSTRING& data, Params& params) {
    // Verify and extract the GeoNetworking Secured Packet as specified in ETSI EN 302 636-4-1 V1.3.1 (2017-08) Clause 9.4 GeoNetworking Secured Packet
    OCTETSTRING unsecured_gn_payload;
    OCTETSTRING secured_data = OCTETSTRING(data.lengthof() - basic_header_len, static_cast<const unsigned char*>(data) + basic_header_len);
    ///////////////////
    if (*static_cast<const unsigned char*>(secured_data) == 0x02) { // This is the old Security version format, discard it
      loggers::get_instance().warning("GeoNetworkingLayer::receiveData: Old security format, discard it");
      return;
    }
    ///////////////////
    if (security_services::get_instance().verify_and_extract_gn_payload(secured_data, _enable_security_checks, unsecured_gn_payload, params) != 0) {
      loggers::get_instance().warning("GeoNetworkingLayer::receiveData: security error");
      loggers::get_instance().warning("GeoNetworkingLayer::receiveData: Security error");
      if (_enable_security_checks) {
        return;
      }
+154 −27
Original line number Diff line number Diff line
@@ -10,7 +10,7 @@ namespace fs = std::experimental::filesystem;

certificates_loader * certificates_loader::instance = nullptr;

certificates_loader::certificates_loader(): _certificateExt{".crt"}, _privateKeyExt{".pkey"}, _publicKeysExt{".vkey"}, _full_path(), _is_cache_initialized{false}, _directory_filter{".svn", "._.DS_Store", ".DS_Store"} {
certificates_loader::certificates_loader(): _certificateExt{".crt"}, _privateKeyExt{".pkey"}, _publicKeysExt{".vkey"}, _hashedidDigestExt{".hashedid"}, _issuerDigestExt{".issuer"}, _full_path(), _is_cache_initialized{false}, _directory_filter{".svn", "._.DS_Store", ".DS_Store"} {
  loggers::get_instance().log(">>> certificates_loader::certificates_loader");
} // End of ctor

@@ -20,12 +20,15 @@ int certificates_loader::build_path(const std::string& p_root_directory) {
  // Build full path
  if (!p_root_directory.empty()) {
    _full_path = p_root_directory;
    if (!std::experimental::filesystem::is_directory(_full_path)) {
      _full_path = "./";
    }
  } else {
    _full_path = "./";
  }
  fs::canonical(_full_path);
  std::experimental::filesystem::canonical(_full_path);
  loggers::get_instance().log("certificates_loader::build_path: full path: %s", _full_path.string().c_str());
  if (!fs::exists(_full_path)) {
  if (!std::experimental::filesystem::exists(_full_path)) {
    loggers::get_instance().warning("certificates_loader::build_path: Invalid path");
    _full_path.clear();
    return -1;
@@ -34,25 +37,23 @@ int certificates_loader::build_path(const std::string& p_root_directory) {
  return 0;
} // End of method build_path

int certificates_loader::load_certificates(std::map<const std::string, std::unique_ptr<security_db_record> >& p_certificates, std::map<const std::vector<unsigned char>, const std::string&>& p_hashed_id8s) {
int certificates_loader::load_certificates(std::map<std::string, std::unique_ptr<security_db_record> >& p_certificates, std::map<std::vector<unsigned char>, std::string>& p_hashed_id8s) {
  loggers::get_instance().log(">>> certificates_loader::load_certificates");

  // Sanity check
  if (_full_path.empty()) {
    return -1;
  }
  
  if (_is_cache_initialized) {
    return 0;
  }
  
  // Retrieve the list of the files in the path
  std::set<fs::path> files;
  std::set<std::experimental::filesystem::path> files;
  if (retrieve_certificates_list(files) == -1) {
    loggers::get_instance().warning("certificates_loader::load_certificates: Failed to build the list of certificate files");
    return -1;
  }
  // Build the certificates cache
  if (build_certificates_cache(files, p_certificates, p_hashed_id8s) == -1) {
    loggers::get_instance().warning("certificates_loader::load_certificates: Failed to build the certificate cache");
    return -1;
  }
  
@@ -65,10 +66,10 @@ int certificates_loader::retrieve_certificates_list(std::set<std::experimental::
  loggers::get_instance().log(">>> certificates_loader::retrieve_certificates_list");

  // Walk through directories
  std::set<fs::path> folders;
  for (const fs::directory_entry it : fs::recursive_directory_iterator(_full_path.string())) {
  std::set<std::experimental::filesystem::path> folders;
  for (const std::experimental::filesystem::directory_entry it : std::experimental::filesystem::recursive_directory_iterator(_full_path.string())) {
    loggers::get_instance().log("certificates_loader::retrieve_certificates_list: Processing directory '%s'", it.path().string().c_str());
    if (fs::is_directory(it)) {
    if (std::experimental::filesystem::is_directory(it)) {
      std::set<std::string>::const_iterator i = _directory_filter.find(it.path().filename());
      if (i != _directory_filter.cend()) {
        loggers::get_instance().log("certificates_loader::retrieve_certificates_list: Exclude directory '%s'", it.path().string().c_str());
@@ -86,11 +87,11 @@ int certificates_loader::retrieve_certificates_list(std::set<std::experimental::
  // Process files
  p_files.clear();
  std::set<std::string> extensions_filter{ _certificateExt, _privateKeyExt, _publicKeysExt };
  for (std::set<fs::path>::const_reverse_iterator f = folders.crbegin(); f != folders.crend(); ++f) {
  for (std::set<std::experimental::filesystem::path>::const_reverse_iterator f = folders.crbegin(); f != folders.crend(); ++f) {
    loggers::get_instance().log("certificates_loader::retrieve_certificates_list: Processing directory '%s'", f->string().c_str());
    for(const fs::directory_entry it : fs::recursive_directory_iterator(*f)) {
    for(const std::experimental::filesystem::directory_entry it : std::experimental::filesystem::recursive_directory_iterator(*f)) {
      loggers::get_instance().log("certificates_loader::retrieve_certificates_list: Processing file '%s'", it.path().filename().string().c_str());
      if (fs::is_regular_file(it)) {
      if (std::experimental::filesystem::is_regular_file(it)) {
        loggers::get_instance().log("certificates_loader::retrieve_certificates_list: Check extension '%s'", it.path().extension().string().c_str());
        std::set<std::string>::const_iterator i = extensions_filter.find(it.path().extension().string());
        if (i != extensions_filter.cend()) {
@@ -109,13 +110,13 @@ int certificates_loader::retrieve_certificates_list(std::set<std::experimental::
  return 0;
} // End of method retrieve_certificates_list

int certificates_loader::build_certificates_cache(std::set<std::experimental::filesystem::path>& p_files, std::map<const std::string, std::unique_ptr<security_db_record> >& p_certificates, std::map<const std::vector<unsigned char>, const std::string&>& p_hashed_id8s) {
int certificates_loader::build_certificates_cache(std::set<std::experimental::filesystem::path>& p_files, std::map<std::string, std::unique_ptr<security_db_record> >& p_certificates, std::map<std::vector<unsigned char>, std::string>& p_hashed_id8s) {
  loggers::get_instance().log(">>> certificates_loader::build_certificates_cache");

  std::set<std::experimental::filesystem::path>::const_iterator it = p_files.cbegin();
  do {
    loggers::get_instance().log("certificates_loader::build_certificates_cache: Caching '%s'", it->string().c_str());
    fs::path p = *it;
    std::experimental::filesystem::path p = *it;
    std::string key = p.filename();
    
    // Load certificate file
@@ -126,12 +127,31 @@ int certificates_loader::build_certificates_cache(std::set<std::experimental::fi
    }
    loggers::get_instance().log("certificates_loader::build_certificates_cache: Caching certificate '%s'", it->string().c_str());
    std::ifstream is(it->string(), ios::in | ios::binary);
    std::vector<unsigned char> certificate(fs::file_size(*it), 0x00);
    std::vector<unsigned char> certificate(std::experimental::filesystem::file_size(*it), 0x00);
    is.read(reinterpret_cast<char *>(certificate.data()), certificate.size());
    is.close();
    // Remove items from the list
    p_files.erase(it);

    // Load private key file
    it = p_files.find(p.replace_extension(_privateKeyExt));
    if (it == p_files.cend()) {
      loggers::get_instance().warning("certificates_loader::build_certificates_cache: Private keys file not found for '%s'", key.c_str());
      return -1;
    }
    loggers::get_instance().log("certificates_loader::build_certificates_cache: Caching private keys '%s'", it->string().c_str());
    is.open(it->string(), ios::in | ios::binary);
    int size = std::experimental::filesystem::file_size(*it);
    if ((size != 32) && (size != 48)) {
      loggers::get_instance().warning("certificates_loader::build_certificates_cache: Private keys file not found for '%s'", key.c_str());
      return -1;
    }
    std::vector<unsigned char> private_key(size, 0x00);
    is.read(reinterpret_cast<char *>(private_key.data()), private_key.size());
    is.close();
    // Remove items from the list
    p_files.erase(it);
    
    // Load public key file
    it = p_files.find(p.replace_extension(_publicKeysExt));
    if (it == p_files.cend()) {
@@ -140,7 +160,7 @@ int certificates_loader::build_certificates_cache(std::set<std::experimental::fi
    }
    loggers::get_instance().log("certificates_loader::build_certificates_cache: Caching public keys '%s'", it->string().c_str());
    is.open(it->string(), ios::in | ios::binary);
    int size = fs::file_size(*it);
    size = std::experimental::filesystem::file_size(*it);
    if ((size != 64) && (size != 96)) {
      loggers::get_instance().warning("certificates_loader::build_certificates_cache: Public keys file not found for '%s'", key.c_str());
      return -1;
@@ -153,26 +173,62 @@ int certificates_loader::build_certificates_cache(std::set<std::experimental::fi
    // Remove items from the list
    p_files.erase(it);

    // FIXME Caching private key, digest and issuer
    // Load issuer
    it = p_files.find(p.replace_extension(_issuerDigestExt));
    if (it == p_files.cend()) {
      loggers::get_instance().warning("certificates_loader::build_certificates_cache: Issuer keys file not found for '%s'", key.c_str());
      return -1;
    }
    loggers::get_instance().log("certificates_loader::build_certificates_cache: Caching issuer keys '%s'", it->string().c_str());
    is.open(it->string(), ios::in | ios::binary);
    size = std::experimental::filesystem::file_size(*it);
    if (size != 8) {
      loggers::get_instance().warning("certificates_loader::build_certificates_cache: Issuer keys file not found for '%s'", key.c_str());
      return -1;
    }
    std::vector<unsigned char> issuer(size, 0x00);
    is.read(reinterpret_cast<char *>(issuer.data()), issuer.size());
    is.close();
    // Remove items from the list
    p_files.erase(it);

    // Load hashed_id
    it = p_files.find(p.replace_extension(_hashedidDigestExt));
    if (it == p_files.cend()) {
      loggers::get_instance().warning("certificates_loader::build_certificates_cache: Hashed_Id keys file not found for '%s'", key.c_str());
      return -1;
    }
    loggers::get_instance().log("certificates_loader::build_certificates_cache: Caching hashed_id keys '%s'", it->string().c_str());
    is.open(it->string(), ios::in | ios::binary);
    size = std::experimental::filesystem::file_size(*it);
    if (size != 8) {
      loggers::get_instance().warning("certificates_loader::build_certificates_cache: Hashed_Id keys file not found for '%s'", key.c_str());
      return -1;
    }
    std::vector<unsigned char> hashed_id(size, 0x00);
    is.read(reinterpret_cast<char *>(hashed_id.data()), hashed_id.size());
    is.close();
    // Remove items from the list
    p_files.erase(it);

    // FIXME create new record
    /*p_certificates.insert(std::pair<const std::string, std::unique_ptr<security_db_record> >(key, std::unique_ptr<security_db_record>(
    // Create new record
    p_certificates.insert(std::pair<const std::string, std::unique_ptr<security_db_record> >(key, std::unique_ptr<security_db_record>(
                                                                                                                                      new security_db_record(
                                                                                                                                                             key,
                                                                                                                                                             certificate, // Certificate
                                                                                                                                                             issuer, // Hashed ID fo the issuer, empty for CA
                                                                                                                                                             h, // Hashed ID
                                                                                                                                                             hashed_id, // Hashed ID
                                                                                                                                                             private_key, // Private key
                                                                                                                                                             public_key_x, // Public key X
                                                                                                                                                             public_key_y // Public key Y
                                                                                                                                                             ))
                                                                                             ));
    std::map<const std::string, std::unique_ptr<security_db_record> >::const_iterator i = p_certificates.find(key);
    if (i == _certificates.cend()) {
    std::map<std::string, std::unique_ptr<security_db_record> >::const_iterator i = p_certificates.find(key);
    if (i == p_certificates.cend()) {
      loggers::get_instance().warning("certificates_loader::build_certificates_cache: Failed to insert new record '%s'", key.c_str());
      return -1;
    }
    p_hashed_id8s.insert(std::pair<const std::vector<unsigned char>, const std::string&>(i->second.get()->hashed_id(), i->first));*/
    p_hashed_id8s.insert(std::pair<std::vector<unsigned char>, std::string>(i->second.get()->hashed_id(), i->first));
    
    // Reset pointer
    it = p_files.cbegin();
@@ -181,3 +237,74 @@ int certificates_loader::build_certificates_cache(std::set<std::experimental::fi
  return 0;
} // End of method build_certificates_cache

int certificates_loader::save_certificate(const security_db_record& p_certificate) {
  loggers::get_instance().log(">>> certificates_loader::save_certificate");

  // Certificate file
  std::experimental::filesystem::path p(_full_path);
  p /= p_certificate.certificate_id();
  p += _certificateExt;//, _privateKeyExt{".pkey"}, _publicKeysExt{".vkey"}
  if (std::experimental::filesystem::exists(p)) {
    std::experimental::filesystem::remove(p);
  }
  loggers::get_instance().log("certificates_loader::save_certificate: Certificate file: '%s'", p.string().c_str());
  std::ofstream os(p.string(), ios::out | ios::binary);
  os.write(reinterpret_cast<const char *>(p_certificate.certificate().data()), p_certificate.certificate().size());
  os.close();
  std::experimental::filesystem::permissions(p, std::experimental::filesystem::perms::add_perms | std::experimental::filesystem::perms::owner_all | std::experimental::filesystem::perms::group_all | std::experimental::filesystem::perms::others_all);

  // Private key
  p = _full_path;
  p /= p_certificate.certificate_id();
  p += _privateKeyExt; // _publicKeysExt{".vkey"}
  if (std::experimental::filesystem::exists(p)) {
    std::experimental::filesystem::remove(p);
  }
  loggers::get_instance().log("certificates_loader::save_certificate: Private key file: '%s'", p.string().c_str());
  os.open(p.string(), ios::out | ios::binary);
  os.write(reinterpret_cast<const char *>(p_certificate.private_key().data()), p_certificate.private_key().size());
  os.close();
  std::experimental::filesystem::permissions(p, std::experimental::filesystem::perms::add_perms | std::experimental::filesystem::perms::owner_all | std::experimental::filesystem::perms::group_all | std::experimental::filesystem::perms::others_all);
  
  // Public keys
  p = _full_path;
  p /= p_certificate.certificate_id();
  p += _publicKeysExt;
  if (std::experimental::filesystem::exists(p)) {
    std::experimental::filesystem::remove(p);
  }
  loggers::get_instance().log("certificates_loader::save_certificate: Public key file: '%s'", p.string().c_str());
  os.open(p.string(), ios::out | ios::binary);
  os.write(reinterpret_cast<const char *>(p_certificate.public_key_x().data()), p_certificate.public_key_x().size());
  os.write(reinterpret_cast<const char *>(p_certificate.public_key_y().data()), p_certificate.public_key_y().size());
  os.close();
  std::experimental::filesystem::permissions(p, std::experimental::filesystem::perms::add_perms | std::experimental::filesystem::perms::owner_all | std::experimental::filesystem::perms::group_all | std::experimental::filesystem::perms::others_all);

  // Issuer
  p = _full_path;
  p /= p_certificate.certificate_id();
  p += _issuerDigestExt;
  if (std::experimental::filesystem::exists(p)) {
    std::experimental::filesystem::remove(p);
  }
  loggers::get_instance().log("certificates_loader::save_certificate: Issuer digest file: '%s'", p.string().c_str());
  os.open(p.string(), ios::out | ios::binary);
  os.write(reinterpret_cast<const char *>(p_certificate.hashed_id_issuer().data()), p_certificate.hashed_id_issuer().size());
  os.close();
  std::experimental::filesystem::permissions(p, std::experimental::filesystem::perms::add_perms | std::experimental::filesystem::perms::owner_all | std::experimental::filesystem::perms::group_all | std::experimental::filesystem::perms::others_all);
   
  // Hashedid8
  p = _full_path;
  p /= p_certificate.certificate_id();
  p += _hashedidDigestExt;
  if (std::experimental::filesystem::exists(p)) {
    std::experimental::filesystem::remove(p);
  }
  loggers::get_instance().log("certificates_loader::save_certificate: Hashedid8 digest file: '%s'", p.string().c_str());
  os.open(p.string(), ios::out | ios::binary);
  os.write(reinterpret_cast<const char *>(p_certificate.hashed_id().data()), p_certificate.hashed_id().size());
  os.close();
  std::experimental::filesystem::permissions(p, std::experimental::filesystem::perms::add_perms | std::experimental::filesystem::perms::owner_all | std::experimental::filesystem::perms::group_all | std::experimental::filesystem::perms::others_all);
  
 return 0;
} // End of method save_certificate
+9 −2
Original line number Diff line number Diff line
@@ -21,6 +21,10 @@ class certificates_loader {

  std::string _publicKeysExt;

  std::string _hashedidDigestExt;

  std::string _issuerDigestExt;

  /*!
   * \brief The full folder path to load certificates
   */
@@ -67,10 +71,13 @@ public: /*! \publicsection */

  int build_path(const std::string& p_root_directory);

  int load_certificates(std::map<const std::string, std::unique_ptr<security_db_record> >& p_certificates, std::map<const std::vector<unsigned char>, const std::string&>& p_hashed_id8s);
  int load_certificates(std::map<std::string, std::unique_ptr<security_db_record> >& p_certificates, std::map<std::vector<unsigned char>, std::string>& p_hashed_id8s);
  //int load_certificate(std::unique_ptr<security_db_record> >& p_certificate, std::map<const std::vector<unsigned char>, const std::string&>& p_hashed_id8s);
  int save_certificate(const security_db_record& p_certificate);

private:
  int retrieve_certificates_list(std::set<std::experimental::filesystem::path>& p_files);

  int build_certificates_cache(std::set<std::experimental::filesystem::path>& p_files, std::map<const std::string, std::unique_ptr<security_db_record> >& p_certificates, std::map<const std::vector<unsigned char>, const std::string&>& p_hashed_id8s);
  int build_certificates_cache(std::set<std::experimental::filesystem::path>& p_files, std::map<std::string, std::unique_ptr<security_db_record> >& p_certificates, std::map<std::vector<unsigned char>, std::string>& p_hashed_id8s);
  
}; // End of class certificates_loader
+21 −101

File changed.

Preview size limit exceeded, changes collapsed.

+3 −3
Original line number Diff line number Diff line
@@ -15,8 +15,9 @@ class CHARSTRING;
 * \brief This class provides security record description for security database
 */
class security_db {
  std::map<const std::string, std::unique_ptr<security_db_record> > _certificates; //! List of the certificates indexed by the certficate identifier
  std::map<const std::vector<unsigned char>, const std::string&> _hashed_id8s; //! List of the certificates indexed by the HashedId8
  // TODO Enforce with const security_db_record, and const std::string
  std::map<std::string, std::unique_ptr<security_db_record> > _certificates; //! List of the certificates indexed by the certficate identifier
  std::map<std::vector<unsigned char>, std::string> _hashed_id8s; //! List of the certificates indexed by the HashedId8
  
public: /*! \publicsection */
  /*!
@@ -46,5 +47,4 @@ public: /*! \publicsection */

private:
  int load_from_files(const std::string& p_db_path);
  int simulate_certificates();
}; // End of class security_db
Loading