pki_layer.cc 7.71 KB
Newer Older
Yann Garcia's avatar
Yann Garcia committed
#include "pki_layer_factory.hh"
#include "codec_stack_builder.hh"

#include "loggers.hh"

Yann Garcia's avatar
Yann Garcia committed
#include "base_time.hh"

#include "registration.hh"

Yann Garcia's avatar
Yann Garcia committed
#include "converter.hh"

Yann Garcia's avatar
Yann Garcia committed
#include "pki_layer.hh"
Yann Garcia's avatar
Yann Garcia committed
using namespace std; // Required for isnan()
Yann Garcia's avatar
Yann Garcia committed
#include "LibItsPki_TypesAndValues.hh"
Yann Garcia's avatar
Yann Garcia committed
#include "LibItsPki_TestSystem.hh"

garciay's avatar
garciay committed
pki_layer::pki_layer(const std::string & p_type, const std::string & param) : t_layer<LibItsPki__TestSystem::PkiPort>(p_type), _params(), _etsi_ts102941_types_enrolment_inner_request(), _etsi_ts102941_types_enrolment_inner_response(), _codec()
Yann Garcia's avatar
Yann Garcia committed
{
  loggers::get_instance().log(">>> pki_layer::pki_layer: %s, %s", to_string().c_str(), param.c_str());

  // Setup parameters
  params::convert(_params, param);
  // Sanity checks
  params::const_iterator it = _params.find(params::certificate);
  if (it == _params.cend()) {
    _params[params::certificate] = "CERT_TS_A_EA";
  }
  it = _params.find(params::peer_certificate);
  if (it == _params.cend()) {
    _params[params::certificate] = "CERT_IUT_A_EA";
  }
garciay's avatar
garciay committed
  _params[params::its_aid] = "2468";
Yann Garcia's avatar
Yann Garcia committed
  _params[params::payload_type] = "";
garciay's avatar
garciay committed
  _params[params::signature] = "NISTP-256";
Yann Garcia's avatar
Yann Garcia committed
  _params[params::encrypted_mode] = "1";
Yann Garcia's avatar
Yann Garcia committed

  // Register this object for AdapterControlPort
  loggers::get_instance().log("pki_layer::pki_layer: Register %s/%p", p_type.c_str(), this);
  registration<pki_layer>::get_instance().add_item(p_type, this);
}

void pki_layer::set_pki_keys(const LibItsPki__TypesAndValues::AcSetSecurityData& p_ac_set_security_data) {
  _ac_set_security_data.reset(new LibItsPki__TypesAndValues::AcSetSecurityData(p_ac_set_security_data));
Yann Garcia's avatar
Yann Garcia committed
}

void pki_layer::sendMsg(const EtsiTs102941TypesEnrolment::InnerEcRequest& p_inner_ec_request, params& p_param) {
garciay's avatar
garciay committed
  loggers::get_instance().log_msg(">>> pki_layer::sendMsg: ", p_inner_ec_request);
Yann Garcia's avatar
Yann Garcia committed

Yann Garcia's avatar
Yann Garcia committed
  // Sanity checks
  if (_ac_set_security_data.get() == nullptr) {
    loggers::get_instance().error("pki_layer::sendMsg: Security data missing");
    return;
  }

  OCTETSTRING inner_ec_request;
  _etsi_ts102941_types_enrolment_inner_request.encode(p_inner_ec_request, inner_ec_request);
  // Build the EtsiTs103097Data-Signed
  OCTETSTRING etsi_ts_102941_data;
  if (generate_inner_ec_request_signed_for_pop(inner_ec_request, etsi_ts_102941_data) == -1) {
    loggers::get_instance().warning("pki_layer::sendMsg: Failed to generate InnerExRequestSignedForPop");
    return;
Yann Garcia's avatar
Yann Garcia committed
  }
Yann Garcia's avatar
Yann Garcia committed
  // Secured the Pki message
  OCTETSTRING signed_and_encrypted_data;
  if (sign_and_encrypt_payload(daetsi_ts_102941_datata, signed_and_encrypted_data) == 0) {
    loggers::get_instance().warning("pki_layer::sendMsg: Failed to secure Pki message");
    return;
  }
  send_data(signed_and_encrypted_data, _params);
garciay's avatar
garciay committed
void pki_layer::sendMsg(const EtsiTs102941TypesEnrolment::InnerEcResponse& p_inner_ec_response, params& p_param) {
  loggers::get_instance().log_msg(">>> pki_layer::sendMsg: ", p_inner_ec_response);
Yann Garcia's avatar
Yann Garcia committed

  OCTETSTRING data;
garciay's avatar
garciay committed
  _etsi_ts102941_types_enrolment_inner_response.encode(p_inner_ec_response, data);
Yann Garcia's avatar
Yann Garcia committed
  // Add security
  OCTETSTRING secured_data;
garciay's avatar
garciay committed
  if (sign_and_encrypt_payload(data, secured_data) == 0) {
Yann Garcia's avatar
Yann Garcia committed
    send_data(data, _params);
  }
}

void pki_layer::send_data(OCTETSTRING& data, params& params) {
  loggers::get_instance().log_msg(">>> pki_layer::send_data: ", data);

  send_to_all_layers(data, params);
}

void pki_layer::receive_data(OCTETSTRING& data, params& params)
{
  loggers::get_instance().log_msg(">>> pki_layer::receive_data: ", data);

garciay's avatar
garciay committed
  // // Decode HTTP message
  // LibItsPki__TypesAndValues::HttpMessage pki_message;
  // if (_codec.decode(data, pki_message) == -1) {
  //   loggers::get_instance().warning("pki_layer::receive_data: Failed to decode data");
  //   return;
  // }
garciay's avatar
garciay committed
  // // Pass it to the ports
  // to_all_upper_ports(pki_message, params);
Yann Garcia's avatar
Yann Garcia committed
int pki_layer::generate_inner_ec_request_signed_for_pop(const OCTETSTRING& p_inner_ec_request, OCTETSTRING& p_etsi_ts_102941_data) {
  loggers::get_instance().log_msg(">>> pki_layer::generate_inner_ec_request_signed_for_pop: ", p_inner_ec_request);

  // Set unsecured data
  IEEE1609dot2::Ieee1609Dot2Content unsecured_data_content;
  unsecured_data_content.unsecuredData() = p_inner_ec_request;
  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;
  // Set secured field
  header_info.psid() = converter::get_instance().string_to_int(p_params[params::its_aid]);
  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();
  INTEGER i;
  i.set_long_long_val((unsigned int) ms);
  header_info.generationTime() = OPTIONAL<INTEGER>(i);
  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;
  loggers::get_instance().log_msg("pki_layer::sign_payload: tbs_data = ", tbs_data);
  // Sign the ToBeSignedData data structure
  IEEE1609dot2BaseTypes::Signature signature;
  if (security_services::get_instance().sign_tbs_data(tbs_data, hashId, signature, p_params) != 0) {
    loggers::get_instance().warning("pki_layer::sign_payload: Failed to secure payload");
    return -1;
  }
  IEEE1609dot2::SignerIdentifier signer;
  loggers::get_instance().log("pki_layer::sign_payload: ms = %d - _last_generation_time = %d - ms - _last_generation_time = %d", (unsigned int) ms, _last_generation_time, (unsigned int) (ms - _last_generation_time));

  signer.self() = nullptr;
  IEEE1609dot2::SignedData signed_data(hashId, tbs_data, signer, signature);
  loggers::get_instance().log_msg("pki_layer::sign_payload: signed_data = ", signed_data);
  IEEE1609dot2::Ieee1609Dot2Content ieee_dot2_content;
  ieee_dot2_content.signedData() = signed_data;
  IEEE1609dot2::Ieee1609Dot2Data ieee_1609dot2_data(pki_layer::ProtocolVersion, ieee_dot2_content);
  loggers::get_instance().log_msg("pki_layer::sign_payload: ieee_1609dot2_data = ", ieee_1609dot2_data);
  // Set EtsiTs102941Data layer
  EtsiTs102941MessagesItss::EtsiTs102941Data etsi_ts_102941_data;
  etsi_ts_102941_data.content().enrolmentRequest = ieee_1609dot2_data;
  _codec.encode(ieee_1609dot2_data, p_etsi_ts_102941_data);
  if (!p_etsi_ts_102941_data.is_bound()) {
    loggers::get_instance().warning("pki_layer::sign_payload: Failed to encode Ieee1609Dot2Data");
    return -1;
  }

  return 0;
}



Yann Garcia's avatar
Yann Garcia committed
int pki_layer::sign_and_encrypt_payload(const OCTETSTRING& p_data, OCTETSTRING& p_secured_data) {
  loggers::get_instance().log_msg(">>> pki_layer::sign_and_encrypt_payload: ", p_data);

garciay's avatar
garciay committed
  // 1. Signed the data
  OCTETSTRING signed_data;
  if (security_services::get_instance().sign_payload(p_data, signed_data, _params) == -1) {
    loggers::get_instance().warning("http_etsi_ieee1609dot2_codec::encode: Failed to sign data");
    return -1;
Yann Garcia's avatar
Yann Garcia committed
  }
garciay's avatar
garciay committed
  loggers::get_instance().log_msg("pki_layer::sign_and_encrypt_payload: signed_data=", signed_data);
  // 2. Encrypt the signed packet
  if (security_services::get_instance().encrypt_gn_payload(signed_data, p_secured_data, _params) == -1) {
    loggers::get_instance().warning("http_etsi_ieee1609dot2_codec::encode: Failed to encrypt data");
    return -1;
  }
  loggers::get_instance().log_msg("<<< http_etsi_ieee1609dot2_codec::encode: ", p_secured_data);
  
  return 0;
Yann Garcia's avatar
Yann Garcia committed
}

pki_layer_factory pki_layer_factory::_f;