Commit 43c80d86 authored by garciay's avatar garciay
Browse files

Add test data for secured beacon

parent da410d0f
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -115,10 +115,8 @@ public:
  
private:
  void send_beacon();

  int build_geonetworking_pdu(OCTETSTRING& data, Params& params);
  int build_secured_geonetworking_pdu(OCTETSTRING& data, Params& params);

  int decode_basic_header(const OCTETSTRING& p_data, LibItsGeoNetworking__TypesAndValues::BasicHeader& p_basic_header);
  
}; // End of class GeoNetworkingLayer
+1 −2
Original line number Diff line number Diff line
@@ -17,9 +17,8 @@ security_db::security_db(const std::string& p_db_path): security_db() {
    simulate_certificates();
  } else {
    load_from_files(p_db_path);
  }

    dump();
  }
} // End of ctor

security_db::~security_db() {
+154 −20
Original line number Diff line number Diff line
@@ -48,31 +48,132 @@ int security_services::verify_and_extract_gn_payload(const OCTETSTRING& p_secure
  IEEE1609dot2::Ieee1609Dot2Data ieee_1609dot2_data;
  EtsiTs103097Codec_Data codec;
  codec.decode(p_secured_gn_payload, ieee_1609dot2_data, &p_params);

  // Sanity checks
  if (!ieee_1609dot2_data.is_bound()) {
    loggers::get_instance().warning("security_services::verify_and_extract_gn_payload: Unbound value, discard it");
    return -1;
  }
  if (p_verify && ((unsigned int)(int)ieee_1609dot2_data.protocolVersion() != security_services::ProtocolVersion)) {
    return -2;
    loggers::get_instance().warning("security_services::verify_and_extract_gn_payload: Wrong version protocol, discard it");
    return -1;
  }

  return process_ieee_dot2_content(ieee_1609dot2_data.content(), p_verify, p_unsecured_gn_payload, p_params);
  return process_ieee_1609_dot2_content(ieee_1609dot2_data.content(), p_verify, p_unsecured_gn_payload, p_params);
} // End of method verify_and_extract_gn_payload

int security_services::process_ieee_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(">>> security_services::process_ieee_dot2_content");
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);
  
  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");
    return -1;
  }
  
  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)) {
      loggers::get_instance().warning("security_services::verify_and_extract_gn_payload: Wrong version protocol, discard it");
      return -1;
    }
    if (process_ieee_1609_dot2_content(ieee_1609dot2_data.content(), p_verify, p_unsecured_payload, p_params) != 0) {
      loggers::get_instance().warning("security_services::verify_and_extract_gn_payload: Failed to process SignedData, discard it");
      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;
  }

  if (!p_ieee_1609_dot2_content.is_bound()) {
    loggers::get_instance().warning("security_services::process_ieee_dot2_content: Unbound value");
  // 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);
  return -1;
} // End of method process_ieee_dot2_content
} // End of method process_ieee_1609_dot2_encrypted_data

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) {
  loggers::get_instance().log_msg(">>> security_services::process_ieee_dot2_content: ", p_unsecured_gn_payload);
  p_params.log();
  loggers::get_instance().log_msg(">>> security_services::secure_gn_payload: ", p_unsecured_gn_payload);
  //p_params.log();

  // Set unsecured data
  IEEE1609dot2::Ieee1609Dot2Content unsecured_data_content;
@@ -102,29 +203,30 @@ int security_services::secure_gn_payload(const OCTETSTRING& p_unsecured_gn_paylo
  IEEE1609dot2::ToBeSignedData tbs_data;
  tbs_data.payload() = payload;
  tbs_data.headerInfo() = header_info;
  loggers::get_instance().log_msg("security_services::process_ieee_dot2_content: tbs_data = ", tbs_data);
  loggers::get_instance().log_msg("security_services::secure_gn_payload: tbs_data = ", tbs_data);
  // Sign the ToBeSignedData data structure
  IEEE1609dot2BaseTypes::Signature signature;
  if (sign_tbs_data(tbs_data, hashId, signature, p_params) != 0) {
    loggers::get_instance().warning("security_services::process_ieee_dot2_content: Failed to secure payload");
    loggers::get_instance().warning("security_services::secure_gn_payload: Failed to secure payload");
    return -1;
  }
  IEEE1609dot2::SignerIdentifier signer;
  std::string certificate_id = p_params[Params::certificate] + "_at";
  loggers::get_instance().log("security_services::process_ieee_dot2_content: certificate_id = %s", certificate_id.c_str());
  loggers::get_instance().log("security_services::secure_gn_payload: certificate_id = %s", certificate_id.c_str());
  if (!p_add_certificate) {
    OCTETSTRING digest;
    if (_security_db->get_hashed_id(certificate_id, digest) != 0) {
      loggers::get_instance().warning("security_services::process_ieee_dot2_content: Failed to secure payload");
      loggers::get_instance().warning("security_services::secure_gn_payload: Failed to secure payload");
    return -1;
    }
    signer.digest() = digest;
  } else { // FIXME Add certifcate case
  } else {
    OCTETSTRING cert;
    if (_security_db->get_certificate(certificate_id, cert) != 0) {
      loggers::get_instance().warning("security_services::process_ieee_dot2_content: Failed to secure payload");
      loggers::get_instance().warning("security_services:secure_gn_payload: Failed to secure payload");
      return -1;
    }
    loggers::get_instance().error("security_services::process_ieee_1609_dot2_content: TODO Add certifcate case");
    // FIXME Need to decode certifcate, shall be done once is security_db
  }
  IEEE1609dot2::SignedData signed_data(
@@ -133,18 +235,18 @@ int security_services::secure_gn_payload(const OCTETSTRING& p_unsecured_gn_paylo
                                       signer,
                                       signature
                                       );
  loggers::get_instance().log_msg("security_services::process_ieee_dot2_content: signed_data = ", signed_data);
  loggers::get_instance().log_msg("security_services::secure_gn_payload: signed_data = ", signed_data);
  IEEE1609dot2::Ieee1609Dot2Content ieee_dot2_content;
  ieee_dot2_content.signedData() = signed_data;
  IEEE1609dot2::Ieee1609Dot2Data ieee_1609dot2_data(
                                                    security_services::ProtocolVersion,
                                                    ieee_dot2_content
                                                    );
  loggers::get_instance().log_msg("security_services::process_ieee_dot2_content: ieee_1609dot2_data = ", ieee_1609dot2_data);
  loggers::get_instance().log_msg("security_services::secure_gn_payload: ieee_1609dot2_data = ", ieee_1609dot2_data);
  EtsiTs103097Codec_Data codec;
  codec.encode(ieee_1609dot2_data, p_secured_gn_payload);
  if (!p_secured_gn_payload.is_bound()) {
    loggers::get_instance().warning("security_services::process_ieee_dot2_content: Failed to encode Ieee1609Dot2Data");
    loggers::get_instance().warning("security_services::secure_gn_payload: Failed to encode Ieee1609Dot2Data");
    return -1;
  }
  
@@ -182,7 +284,11 @@ int security_services::sign_tbs_data(const IEEE1609dot2::ToBeSignedData& p_tbs_d
  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);
  } // FIXME To be continued
  } else {
    // TODO Add other signature algorithm
    loggers::get_instance().error("security_services::process_ieee_1609_dot2_content: TODO Add other signature algorithm");
    result = -1;
  }
  if (result != 0) {
    loggers::get_instance().warning("security_services::sign_tbs_data: Failed to sign payload");
    return -1;
@@ -255,3 +361,31 @@ int security_services::sign_ecdsa_nistp256(const OCTETSTRING& p_hash, IEEE1609do
  return 0;
}

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;
}
+6 −2
Original line number Diff line number Diff line
@@ -18,6 +18,8 @@ namespace IEEE1609dot2 {
  class Ieee1609Dot2Data;
  class Ieee1609Dot2Content;
  class ToBeSignedData;
  class SignedData;
  class EncryptedData;
  class SignerIdentifier;
}

@@ -85,12 +87,14 @@ private:
   * \param[in] p_unsecured_payload The extracted payload
   * \return 0 on success, negative value otherwise
   */
  int process_ieee_dot2_content(const IEEE1609dot2::Ieee1609Dot2Content& p_ieee_1609_dot2_content, const bool p_verify, OCTETSTRING& p_unsecured_payload, Params& p_params);

  int process_ieee_1609_dot2_content(const IEEE1609dot2::Ieee1609Dot2Content& p_ieee_1609_dot2_content, const bool p_verify, OCTETSTRING& p_unsecured_payload, Params& p_params);
  int process_ieee_1609_dot2_signed_data(const IEEE1609dot2::SignedData& p_signed_data, const bool p_verify, OCTETSTRING& p_unsecured_payload, Params& p_params);
  int process_ieee_1609_dot2_encrypted_data(const IEEE1609dot2::EncryptedData& p_encrypted_data, const bool p_verify, OCTETSTRING& p_unsecured_payload, Params& p_params);
  int sign_tbs_data(const IEEE1609dot2::ToBeSignedData& p_tbs_data, const IEEE1609dot2BaseTypes::HashAlgorithm& p_hashAlgorithm, IEEE1609dot2BaseTypes::Signature& p_signature, Params& p_params);

  int hash_sha256(const OCTETSTRING& p_data, OCTETSTRING& p_hash_data);
  int hash_sha384(const OCTETSTRING& p_data, OCTETSTRING& p_hash_data);
  int sign_ecdsa_nistp256(const OCTETSTRING& p_hash, IEEE1609dot2BaseTypes::Signature& p_signature, Params& p_params);
  int verify_sign_ecdsa_nistp256(const OCTETSTRING& p_hash, const IEEE1609dot2BaseTypes::Signature& p_signature, const std::string& p_certificate_id, Params& p_params);

}; // End of class security_services