security_services.cc 82.8 KB
Newer Older
Yann Garcia's avatar
Yann Garcia committed
  // Generate the hash to be verified: Hash ( Hash (Data input) || Hash (Signer identifier input) )
  OCTETSTRING issuer; // Hash (Signer identifier input)
  if (_security_db->get_hash(p_certificate_id, issuer) != 0) {
    loggers::get_instance().warning("security_services::verify_sign_ecdsa_brainpoolp256r1 (%s): Failed to get hash of the issuer certificate", p_certificate_id.c_str());
    return -1;
  }
  loggers::get_instance().log_msg("security_services::verify_sign_ecdsa_brainpoolp256r1: hash_issuer: ", issuer);
  OCTETSTRING hash_data = p_hash + issuer; // Hash (Data input) || Hash (Signer identifier input)
  loggers::get_instance().log_msg("security_services::verify_sign_ecdsa_brainpoolp256r1: hash: ", hash_data);
  OCTETSTRING hash_to_be_verified;
  hash_sha256(hash_data, hash_to_be_verified); // Hash ( Hash (Data input) || Hash (Signer identifier input) )
  loggers::get_instance().log_msg("security_services::verify_sign_ecdsa_brainpoolp256r1: hash_to_be_verified: ", hash_to_be_verified);

  // Build the signature
  OCTETSTRING signature;
  if (p_signature.ecdsaBrainpoolP256r1Signature().rSig().ischosen(IEEE1609dot2BaseTypes::EccP256CurvePoint::ALT_x__only)) {
    signature = p_signature.ecdsaBrainpoolP256r1Signature().rSig().x__only() + p_signature.ecdsaBrainpoolP256r1Signature().sSig();
  } else if (p_signature.ecdsaBrainpoolP256r1Signature().rSig().ischosen(IEEE1609dot2BaseTypes::EccP256CurvePoint::ALT_compressed__y__0)) {
    signature = p_signature.ecdsaBrainpoolP256r1Signature().rSig().compressed__y__0() + p_signature.ecdsaBrainpoolP256r1Signature().sSig();
  } else if (p_signature.ecdsaBrainpoolP256r1Signature().rSig().ischosen(IEEE1609dot2BaseTypes::EccP256CurvePoint::ALT_compressed__y__1)) {
    signature = p_signature.ecdsaBrainpoolP256r1Signature().rSig().compressed__y__1() + p_signature.ecdsaBrainpoolP256r1Signature().sSig();
  } else if (p_signature.ecdsaBrainpoolP256r1Signature().rSig().ischosen(IEEE1609dot2BaseTypes::EccP256CurvePoint::ALT_uncompressedP256)) {
    signature = p_signature.ecdsaBrainpoolP256r1Signature().rSig().uncompressedP256().x() + p_signature.ecdsaBrainpoolP256r1Signature().rSig().uncompressedP256().y() + p_signature.ecdsaBrainpoolP256r1Signature().sSig();
  } else {
    loggers::get_instance().warning("security_services::verify_sign_ecdsa_brainpoolp256r1 (%s): Invalid curve point", p_certificate_id.c_str());
    return -1;
  }
  security_ecc k(ec_elliptic_curves::brainpool_p_256_r1, public_key_x, public_key_y);
  if (k.sign_verif(hash_to_be_verified, signature) == 0) {
    return 0;
  }
  
  return -1;
}

int security_services::sign_ecdsa_brainpoolp384r1(const OCTETSTRING& p_hash, IEEE1609dot2BaseTypes::Signature& p_signature, params& p_params) {
  loggers::get_instance().log_msg(">>> security_services::sign_ecdsa_brainpoolp384r1: ", p_hash);
  
  std::string certificate_id = p_params[params::certificate];
  loggers::get_instance().log("security_services::sign_ecdsa_brainpoolp384r1: encoded certificate_id = '%s'", certificate_id.c_str());
  OCTETSTRING pkey;
  if (_security_db->get_private_key(certificate_id, pkey) != 0) {
    loggers::get_instance().warning("security_services::sign_ecdsa_brainpoolp384r1: Failed to get private key");
    return -1;
  }
  // Hash ( Hash (Data input) || Hash (Signer identifier input) )
  OCTETSTRING hash_cert;
  if (_security_db->get_hash(certificate_id, hash_cert) != 0) {
    loggers::get_instance().warning("security_services::sign_ecdsa_brainpoolp384r1: Failed to get whole hash certificate");
    return -1;
  }
  loggers::get_instance().log_msg("security_services::sign_ecdsa_brainpoolp384r1: hash_issuer: ", hash_cert);
  OCTETSTRING os = p_hash + hash_cert; // Hash (Data input) || Hash (Signer identifier input)
  loggers::get_instance().log_msg("security_services::sign_ecdsa_brainpoolp384r1: hash: ", os);
  OCTETSTRING hashed_data;
  hash_sha384(os, hashed_data); // Hash ( Hash (Data input) || Hash (Signer identifier input) )
  security_ecc k(ec_elliptic_curves::brainpool_p_384_r1, pkey);
  OCTETSTRING r_sig;
  OCTETSTRING s_sig;
  if (k.sign(hashed_data, r_sig, s_sig) != 0) {
    loggers::get_instance().warning("security_services::sign_ecdsa_brainpoolp384r1: Failed to sign payload");
    return -1;
  }
  IEEE1609dot2BaseTypes::EccP384CurvePoint ep;
  ep.x__only() = r_sig;
  p_signature.ecdsaBrainpoolP384r1Signature() = IEEE1609dot2BaseTypes::EcdsaP384Signature(
                                                                                          ep,
                                                                                          s_sig
                                                                                          );
  loggers::get_instance().log_msg("security_services::sign_ecdsa_brainpoolp384r1: signature=", p_signature);
  
  return 0;
}

int security_services::verify_sign_ecdsa_brainpoolp384r1(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_brainpoolp384r1:", p_hash);
  loggers::get_instance().log(">>> security_services::verify_sign_ecdsa_brainpoolp384r1: %s", p_certificate_id.c_str());
  
  OCTETSTRING public_key_x;
  OCTETSTRING public_key_y;
  if (_security_db->get_public_keys(p_certificate_id, public_key_x, public_key_y) != 0) {
    loggers::get_instance().warning("security_services::verify_sign_ecdsa_brainpoolp384r1 (%s): Failed to get public keys", p_certificate_id.c_str());
    return -1;
  }
  
  // Generate the hash to be verified: Hash ( Hash (Data input) || Hash (Signer identifier input) )
  OCTETSTRING issuer; // Hash (Signer identifier input)
  if (_security_db->get_hash(p_certificate_id, issuer) != 0) {
    loggers::get_instance().warning("security_services::verify_sign_ecdsa_brainpoolp384r1 (%s): Failed to get hash of the issuer certificate", p_certificate_id.c_str());
    return -1;
  }
  loggers::get_instance().log_msg("security_services::verify_sign_ecdsa_brainpoolp384r1: hash_issuer: ", issuer);
  OCTETSTRING hash_data = p_hash + issuer; // Hash (Data input) || Hash (Signer identifier input)
  loggers::get_instance().log_msg("security_services::verify_sign_ecdsa_brainpoolp384r1: hash: ", hash_data);
  OCTETSTRING hash_to_be_verified;
  hash_sha384(hash_data, hash_to_be_verified); // Hash ( Hash (Data input) || Hash (Signer identifier input) )
  loggers::get_instance().log_msg("security_services::verify_sign_ecdsa_brainpoolp384r1: hash_to_be_verified: ", hash_to_be_verified);

  // Build the signature
  OCTETSTRING signature;
  if (p_signature.ecdsaBrainpoolP384r1Signature().rSig().ischosen(IEEE1609dot2BaseTypes::EccP384CurvePoint::ALT_x__only)) {
    signature = p_signature.ecdsaBrainpoolP384r1Signature().rSig().x__only() + p_signature.ecdsaBrainpoolP384r1Signature().sSig();
  } else if (p_signature.ecdsaBrainpoolP384r1Signature().rSig().ischosen(IEEE1609dot2BaseTypes::EccP384CurvePoint::ALT_compressed__y__0)) {
    signature = p_signature.ecdsaBrainpoolP384r1Signature().rSig().compressed__y__0() + p_signature.ecdsaBrainpoolP384r1Signature().sSig();
  } else if (p_signature.ecdsaBrainpoolP384r1Signature().rSig().ischosen(IEEE1609dot2BaseTypes::EccP384CurvePoint::ALT_compressed__y__1)) {
    signature = p_signature.ecdsaBrainpoolP384r1Signature().rSig().compressed__y__1() + p_signature.ecdsaBrainpoolP384r1Signature().sSig();
  } else if (p_signature.ecdsaBrainpoolP384r1Signature().rSig().ischosen(IEEE1609dot2BaseTypes::EccP384CurvePoint::ALT_uncompressedP384)) {
    signature = p_signature.ecdsaBrainpoolP384r1Signature().rSig().uncompressedP384().x() + p_signature.ecdsaBrainpoolP384r1Signature().rSig().uncompressedP384().y() + p_signature.ecdsaBrainpoolP384r1Signature().sSig();
  } else {
    loggers::get_instance().warning("security_services::verify_sign_ecdsa_brainpoolp384r1 (%s): Invalid curve point", p_certificate_id.c_str());
    return -1;
  }
  security_ecc k(ec_elliptic_curves::brainpool_p_384_r1, public_key_x, public_key_y);
  if (k.sign_verif(hash_to_be_verified, signature) == 0) {
    return 0;
  }
  
  return -1;
}

int security_services::extract_verification_keys(const IEEE1609dot2::CertificateBase& p_cert, OCTETSTRING& p_public_key_x, OCTETSTRING& p_public_key_y, OCTETSTRING& p_public_comp_key, INTEGER& p_public_comp_key_mode) {
  loggers::get_instance().log("security_services::extract_verification_keys");
  
  if (p_cert.toBeSigned().verifyKeyIndicator().verificationKey().ischosen(IEEE1609dot2BaseTypes::PublicVerificationKey::ALT_ecdsaNistP256)) {
    if (p_cert.toBeSigned().verifyKeyIndicator().verificationKey().ecdsaNistP256().ischosen(IEEE1609dot2BaseTypes::EccP256CurvePoint::ALT_compressed__y__0)) {
      p_public_comp_key = p_cert.toBeSigned().verifyKeyIndicator().verificationKey().ecdsaNistP256().compressed__y__0();
      security_ecc ecc(ec_elliptic_curves::nist_p_256, p_public_comp_key, ecc_compressed_mode::compressed_y_0);
      p_public_key_x = ecc.public_key_x();
      p_public_key_y = ecc.public_key_y();
      p_public_comp_key_mode = INTEGER(0);
    } else if (p_cert.toBeSigned().verifyKeyIndicator().verificationKey().ecdsaNistP256().ischosen(IEEE1609dot2BaseTypes::EccP256CurvePoint::ALT_compressed__y__1)) {
      p_public_comp_key = p_cert.toBeSigned().verifyKeyIndicator().verificationKey().ecdsaNistP256().compressed__y__1();
      security_ecc ecc(ec_elliptic_curves::nist_p_256, p_public_comp_key, ecc_compressed_mode::compressed_y_1);
      p_public_key_x = ecc.public_key_x();
      p_public_key_y = ecc.public_key_y();
      p_public_comp_key_mode = INTEGER(1);
    } else if (p_cert.toBeSigned().verifyKeyIndicator().verificationKey().ecdsaNistP256().ischosen(IEEE1609dot2BaseTypes::EccP256CurvePoint::ALT_uncompressedP256)) {
YannGarcia's avatar
YannGarcia committed
      security_ecc ecc(ec_elliptic_curves::nist_p_256, p_cert.toBeSigned().verifyKeyIndicator().verificationKey().ecdsaNistP256().uncompressedP256().x(), p_cert.toBeSigned().verifyKeyIndicator().verificationKey().ecdsaNistP256().uncompressedP256().y());
      p_public_comp_key = ecc.public_key_compressed();
      p_public_comp_key_mode = INTEGER((int)ecc.public_key_compressed_mode());
      p_public_key_x = p_cert.toBeSigned().verifyKeyIndicator().verificationKey().ecdsaNistP256().uncompressedP256().x();
      p_public_key_y = p_cert.toBeSigned().verifyKeyIndicator().verificationKey().ecdsaNistP256().uncompressedP256().y();
    } else {
      loggers::get_instance().error("security_services::extract_verification_keys: Unsupported VerificationKey");
      return -1;
    }
  } else if (p_cert.toBeSigned().verifyKeyIndicator().verificationKey().ischosen(IEEE1609dot2BaseTypes::PublicVerificationKey::ALT_ecdsaBrainpoolP256r1)) {
    if (p_cert.toBeSigned().verifyKeyIndicator().verificationKey().ecdsaBrainpoolP256r1().ischosen(IEEE1609dot2BaseTypes::EccP256CurvePoint::ALT_compressed__y__0)) {
      p_public_comp_key = p_cert.toBeSigned().verifyKeyIndicator().verificationKey().ecdsaBrainpoolP256r1().compressed__y__0();
      security_ecc ecc(ec_elliptic_curves::brainpool_p_256_r1, p_public_comp_key, ecc_compressed_mode::compressed_y_0);
      p_public_key_x = ecc.public_key_x();
      p_public_key_y = ecc.public_key_y();
      p_public_comp_key_mode = INTEGER(0);
    } else if (p_cert.toBeSigned().verifyKeyIndicator().verificationKey().ecdsaBrainpoolP256r1().ischosen(IEEE1609dot2BaseTypes::EccP256CurvePoint::ALT_compressed__y__1)) {
      p_public_comp_key = p_cert.toBeSigned().verifyKeyIndicator().verificationKey().ecdsaBrainpoolP256r1().compressed__y__1();
      security_ecc ecc(ec_elliptic_curves::brainpool_p_256_r1, p_public_comp_key, ecc_compressed_mode::compressed_y_1);
      p_public_key_x = ecc.public_key_x();
      p_public_key_y = ecc.public_key_y();
      p_public_comp_key_mode = INTEGER(1);
    } else if (p_cert.toBeSigned().verifyKeyIndicator().verificationKey().ecdsaBrainpoolP256r1().ischosen(IEEE1609dot2BaseTypes::EccP256CurvePoint::ALT_uncompressedP256)) {
      p_public_key_x = p_cert.toBeSigned().verifyKeyIndicator().verificationKey().ecdsaBrainpoolP256r1().uncompressedP256().x();
      p_public_key_y = p_cert.toBeSigned().verifyKeyIndicator().verificationKey().ecdsaBrainpoolP256r1().uncompressedP256().y();
    } else if (p_cert.toBeSigned().verifyKeyIndicator().verificationKey().ischosen(IEEE1609dot2BaseTypes::PublicVerificationKey::ALT_ecdsaBrainpoolP384r1)) {
      p_public_comp_key = p_cert.toBeSigned().verifyKeyIndicator().verificationKey().ecdsaBrainpoolP384r1().compressed__y__0();
      security_ecc ecc(ec_elliptic_curves::brainpool_p_384_r1, p_public_comp_key, ecc_compressed_mode::compressed_y_0);
      p_public_key_x = ecc.public_key_x();
      p_public_key_y = ecc.public_key_y();
      p_public_comp_key_mode = INTEGER(0);
    } else if (p_cert.toBeSigned().verifyKeyIndicator().verificationKey().ecdsaBrainpoolP384r1().ischosen(IEEE1609dot2BaseTypes::EccP384CurvePoint::ALT_compressed__y__1)) {
      p_public_comp_key = p_cert.toBeSigned().verifyKeyIndicator().verificationKey().ecdsaBrainpoolP384r1().compressed__y__1();
      security_ecc ecc(ec_elliptic_curves::brainpool_p_384_r1, p_public_comp_key, ecc_compressed_mode::compressed_y_1);
      p_public_key_x = ecc.public_key_x();
      p_public_key_y = ecc.public_key_y();
      p_public_comp_key_mode = INTEGER(1);
    } else if (p_cert.toBeSigned().verifyKeyIndicator().verificationKey().ecdsaBrainpoolP384r1().ischosen(IEEE1609dot2BaseTypes::EccP384CurvePoint::ALT_uncompressedP384)) {
      p_public_key_x = p_cert.toBeSigned().verifyKeyIndicator().verificationKey().ecdsaBrainpoolP384r1().uncompressedP384().x();
      p_public_key_y = p_cert.toBeSigned().verifyKeyIndicator().verificationKey().ecdsaBrainpoolP384r1().uncompressedP384().y();
    } else {
      loggers::get_instance().error("security_services::extract_verification_keys: Unsupported VerificationKey");
      return -1;
    }
  } else {
    loggers::get_instance().error("security_services::extract_verification_keys: Unsupported VerificationKey");
    return -1;
  }

  return 0;
}

int security_services::extract_encryption_keys(const IEEE1609dot2::CertificateBase& p_cert, OCTETSTRING& p_public_enc_key_x, OCTETSTRING& p_public_enc_key_y, OCTETSTRING& p_public_enc_comp_key, INTEGER& p_public_enc_comp_key_mode) {
  loggers::get_instance().log("security_services::extract_encryption_keys");
  
  if (p_cert.toBeSigned().encryptionKey().ispresent()) {
    const IEEE1609dot2BaseTypes::PublicEncryptionKey& p = static_cast<const IEEE1609dot2BaseTypes::PublicEncryptionKey&>(p_cert.toBeSigned().encryptionKey());
    if (p.publicKey().ischosen(IEEE1609dot2BaseTypes::BasePublicEncryptionKey::ALT_eciesNistP256)) {
      if (p.publicKey().eciesNistP256().ischosen(IEEE1609dot2BaseTypes::EccP256CurvePoint::ALT_compressed__y__0)) {
        p_public_enc_comp_key = p.publicKey().eciesNistP256().compressed__y__0();
        security_ecc ecc(ec_elliptic_curves::nist_p_256, p_public_enc_comp_key, ecc_compressed_mode::compressed_y_0);
        p_public_enc_key_x = ecc.public_key_x();
        p_public_enc_key_y = ecc.public_key_y();
        p_public_enc_comp_key_mode = INTEGER(0);
      } else if (p.publicKey().eciesNistP256().ischosen(IEEE1609dot2BaseTypes::EccP256CurvePoint::ALT_compressed__y__1)) {
        const OCTETSTRING& p_public_enc_comp_key = p.publicKey().eciesNistP256().compressed__y__1();
        security_ecc ecc(ec_elliptic_curves::nist_p_256, p_public_enc_comp_key, ecc_compressed_mode::compressed_y_1);
        p_public_enc_key_x = ecc.public_key_x();
        p_public_enc_key_y = ecc.public_key_y();
        p_public_enc_comp_key_mode = INTEGER(1);
      } else if (p.publicKey().eciesNistP256().ischosen(IEEE1609dot2BaseTypes::EccP256CurvePoint::ALT_uncompressedP256)) {
        p_public_enc_key_x = p.publicKey().eciesNistP256().uncompressedP256().x();
        p_public_enc_key_y = p.publicKey().eciesNistP256().uncompressedP256().y();
      } else {
        loggers::get_instance().error("security_services::extract_encryption_keys: Unsupported EncryptionKey");
        return -1;
      }
    } else if (p.publicKey().ischosen(IEEE1609dot2BaseTypes::BasePublicEncryptionKey::ALT_eciesBrainpoolP256r1)) {
      if (p.publicKey().eciesBrainpoolP256r1().ischosen(IEEE1609dot2BaseTypes::EccP256CurvePoint::ALT_compressed__y__0)) {
        p_public_enc_comp_key = p.publicKey().eciesBrainpoolP256r1().compressed__y__0();
        security_ecc ecc(ec_elliptic_curves::brainpool_p_256_r1, p_public_enc_comp_key, ecc_compressed_mode::compressed_y_0);
        p_public_enc_key_x = ecc.public_key_x();
        p_public_enc_key_y = ecc.public_key_y();
        p_public_enc_comp_key_mode = INTEGER(0);
      } else if (p.publicKey().eciesBrainpoolP256r1().ischosen(IEEE1609dot2BaseTypes::EccP256CurvePoint::ALT_compressed__y__1)) {
        p_public_enc_comp_key = p.publicKey().eciesBrainpoolP256r1().compressed__y__1();
        security_ecc ecc(ec_elliptic_curves::brainpool_p_256_r1, p_public_enc_comp_key, ecc_compressed_mode::compressed_y_1);
        p_public_enc_key_x = ecc.public_key_x();
        p_public_enc_key_y = ecc.public_key_y();
        p_public_enc_comp_key_mode = INTEGER(1);
      } else if (p.publicKey().eciesBrainpoolP256r1().ischosen(IEEE1609dot2BaseTypes::EccP256CurvePoint::ALT_uncompressedP256)) {
        p_public_enc_key_x = p.publicKey().eciesBrainpoolP256r1().uncompressedP256().x();
        p_public_enc_key_y = p.publicKey().eciesBrainpoolP256r1().uncompressedP256().y();
      } else {
        loggers::get_instance().error("security_services::extract_encryption_keys: Unsupported EncryptionKey");
        return -1;
      }
    } else {
      loggers::get_instance().error("security_services::extract_encryption_keys: Unsupported EncryptionKey");
      return -1;
    }
  } else {
    loggers::get_instance().warning("security_services::extract_encryption_keys: EncryptionKey omitted");
garciay's avatar
garciay committed
    p_public_enc_key_x = OCTETSTRING(0, nullptr);
    p_public_enc_key_y = OCTETSTRING(0, nullptr);
    p_public_enc_comp_key = OCTETSTRING(0, nullptr);
    return 0; // Normal termination
  }

  return 0;
} // End of method extract_encryption_keys

 int security_services::extract_and_store_certificate(const IEEE1609dot2::CertificateBase& p_certificate, std::string& p_certificate_id) {
  loggers::get_instance().log_msg(">>> security_services::extract_and_store_certificate: ", p_certificate);

  // Encode certificate
  etsi_ts103097_certificate_codec codec;
  OCTETSTRING enc_cert;
  codec.encode(p_certificate, enc_cert);
  if (enc_cert.lengthof() == 0) {
    loggers::get_instance().warning("security_services::extract_and_store_certificate: Failed to encode certificate");
    return -1;
  }
  loggers::get_instance().log_msg("security_services::extract_and_store_certificate: Encoded certificate=", enc_cert);
YannGarcia's avatar
YannGarcia committed
  OCTETSTRING hash_cert_sha_256;
  hash_sha256(enc_cert, hash_cert_sha_256);
  loggers::get_instance().log_msg("security_services::extract_and_store_certificate: hash_cert_sha_256= ", hash_cert_sha_256);
  int result = -1;
  if (p_certificate.issuer().ischosen(IEEE1609dot2::IssuerIdentifier::ALT_sha256AndDigest)) {
    // Calculate the hash according to the hashId
YannGarcia's avatar
YannGarcia committed
    OCTETSTRING hash_cert(hash_cert_sha_256);
    loggers::get_instance().log_msg("security_services::extract_and_store_certificate: hash_cert= ", hash_cert);
    const OCTETSTRING hashed_id8 = substr(hash_cert, hash_cert.lengthof() - 8, 8);
    // Retrieve the certificate identifier from digest
    loggers::get_instance().log_msg("security_services::extract_and_store_certificate: Retrieve the certificate identifier from digest: ", hashed_id8);
    result = _security_db.get()->get_certificate_id(hashed_id8, p_certificate_id);
    if (result == -1) { // Not found in current DB
      if (_security_cache.get()->get_certificate_id(hashed_id8, p_certificate_id) == -1) { // Not found in TS cache
        loggers::get_instance().log_msg("security_services::extract_and_store_certificate: Store new certificate in cache: ", p_certificate);
        // const std::vector<unsigned char> v(static_cast<const unsigned char*>(hashed_id8), static_cast<const unsigned char*>(hashed_id8) + hashed_id8.lengthof());
        // p_certificate_id = converter::get_instance().bytes_to_hexa(v);
Yann Garcia's avatar
Yann Garcia committed
        p_certificate_id = std::string(static_cast<const char*>(hex2str(oct2hex(hashed_id8))));
        // Add it into the cache
        OCTETSTRING public_key_x, public_key_y, public_comp_key;
        INTEGER public_comp_key_mode;
        if (extract_verification_keys(p_certificate, public_key_x, public_key_y, public_comp_key, public_comp_key_mode) == -1) {
          loggers::get_instance().error("security_services::extract_and_store_certificate: Unsupported EncryptionKey");
          return -1;
        }
        // Add encryption keys
        OCTETSTRING public_enc_key_x, public_enc_key_y, public_enc_comp_key;
        INTEGER public_enc_comp_key_mode;
        if (extract_encryption_keys(p_certificate, public_enc_key_x, public_enc_key_y, public_enc_comp_key, public_enc_comp_key_mode) == -1) {
          loggers::get_instance().error("security_services::extract_and_store_certificate: Unsupported EncryptionKey");
          return -1;
        }
        // And store it into the cache
        _security_cache.get()->store_certificate(
                                                 CHARSTRING(p_certificate_id.c_str()),
                                                 enc_cert,
                                                 int2oct(0, 32), // No way to get the private key here
                                                 public_key_x,
                                                 public_key_y,
                                                 public_comp_key,
                                                 public_comp_key_mode,
                                                 hash_cert,
YannGarcia's avatar
YannGarcia committed
                                                 hash_cert_sha_256,
garciay's avatar
garciay committed
                                                 hashed_id8,
                                                 p_certificate.issuer().sha256AndDigest(),
garciay's avatar
garciay committed
                                                 OCTETSTRING(0, nullptr), // Encryption private not used
                                                 public_enc_key_x,
                                                 public_enc_key_y,
                                                 public_enc_comp_key,
                                                 public_enc_comp_key_mode
                                                 );
      }
    }
  } else if (p_certificate.issuer().ischosen(IEEE1609dot2::IssuerIdentifier::ALT_sha384AndDigest)) {
    // Calculate the hash according to the hashId
    OCTETSTRING hash_cert;
    hash_sha384(enc_cert, hash_cert);
    loggers::get_instance().log_msg("security_services::extract_and_store_certificate: hash_cert= ", hash_cert);
    const OCTETSTRING hashed_id8 = substr(hash_cert, hash_cert.lengthof() - 8, 8);
    // Retrieve the certificate identifier from digest
    loggers::get_instance().log("security_services::extract_and_store_certificate: Retrieve the certificate identifier from digest");
    result = _security_db.get()->get_certificate_id(hashed_id8, p_certificate_id);
    if (result == -1) {
      if (_security_cache.get()->get_certificate_id(hashed_id8, p_certificate_id) == -1) {
        loggers::get_instance().log_msg("security_services::extract_and_store_certificate: Store new certificate in cache: ", p_certificate);
        // const std::vector<unsigned char> v(static_cast<const unsigned char*>(hashed_id8), static_cast<const unsigned char*>(hashed_id8) + hashed_id8.lengthof());
        // p_certificate_id = converter::get_instance().bytes_to_hexa(v);
Yann Garcia's avatar
Yann Garcia committed
        p_certificate_id = std::string(static_cast<const char*>(hex2str(oct2hex(hashed_id8))));
        // Add it into the cache
        OCTETSTRING public_key_x, public_key_y, public_comp_key;
        INTEGER public_comp_key_mode;
        if (extract_verification_keys(p_certificate, public_key_x, public_key_y, public_comp_key, public_comp_key_mode) == -1) {
          loggers::get_instance().error("security_services::extract_and_store_certificate: Unsupported EncryptionKey");
          return -1;
        }
        // Add encryption keys
        OCTETSTRING public_enc_key_x, public_enc_key_y, public_enc_comp_key;
        INTEGER public_enc_comp_key_mode;
        if (extract_encryption_keys(p_certificate, public_enc_key_x, public_enc_key_y, public_enc_comp_key, public_enc_comp_key_mode) == -1) {
          loggers::get_instance().error("security_services::extract_and_store_certificate: Unsupported EncryptionKey");
          return -1;
        }
        // And store it into the cache
        _security_cache.get()->store_certificate(
                                                 CHARSTRING(p_certificate_id.c_str()),
                                                 enc_cert,
                                                 int2oct(0, 48), // No way to get the private key here
                                                 public_key_x,
                                                 public_key_y,
                                                 public_comp_key,
                                                 public_comp_key_mode,
                                                 hash_cert,
YannGarcia's avatar
YannGarcia committed
                                                 hash_cert_sha_256,
garciay's avatar
garciay committed
                                                 hashed_id8,
                                                 p_certificate.issuer().sha384AndDigest(),
garciay's avatar
garciay committed
                                                 OCTETSTRING(0, nullptr), // Encryption private not used
                                                 public_enc_key_x,
                                                 public_enc_key_y,
                                                 public_enc_comp_key,
                                                 public_enc_comp_key_mode
                                                 );
      }
    }
  } else {
    loggers::get_instance().error("security_services::extract_and_store_certificate: Unsupported issuer");
    return -1;
  }
  
  return 0;
} // End of method extract_and_store_certificate

int security_services::read_certificate(const CHARSTRING& p_certificate_id, OCTETSTRING& p_certificate) const {
  return _security_db.get()->get_certificate(std::string(static_cast<const char*>(p_certificate_id)), p_certificate);
}
  
int security_services::read_certificate_digest(const CHARSTRING& p_certificate_id, OCTETSTRING& p_digest) const {
  return _security_db.get()->get_hashed_id(std::string(static_cast<const char*>(p_certificate_id)), p_digest);
}

int security_services::read_certificate_hash(const CHARSTRING& p_certificate_id, OCTETSTRING& p_hash) const {
  return _security_db.get()->get_hash(std::string(static_cast<const char*>(p_certificate_id)), p_hash);
}

YannGarcia's avatar
YannGarcia committed
int security_services::read_certificate_hash_sha_256(const CHARSTRING& p_certificate_id, OCTETSTRING& p_hash) const {
  return _security_db.get()->get_hash_sha_256(std::string(static_cast<const char*>(p_certificate_id)), p_hash);
}

int security_services::read_certificate_from_digest(const OCTETSTRING& p_digest, CHARSTRING& p_certificate_id) const {
  std::string certificate_id;
  if (_security_db.get()->get_certificate_id(p_digest, certificate_id) != -1) {
    p_certificate_id = CHARSTRING(certificate_id.c_str());
    return 0;
  }
  return -1;
}

Yann Garcia's avatar
Yann Garcia committed
int security_services::read_certificate_from_hashed_id3(const OCTETSTRING& p_digest, CHARSTRING& p_certificate_id) const {
  std::string certificate_id;
  if (_security_db.get()->get_certificate_hashed_id3(p_digest, certificate_id) != -1) {
    p_certificate_id = CHARSTRING(certificate_id.c_str());
    return 0;
  }
  return -1;
}

int security_services::read_private_key(const CHARSTRING& p_certificate_id, OCTETSTRING& p_private_key) const {
  return _security_db.get()->get_private_key(std::string(static_cast<const char*>(p_certificate_id)), p_private_key);
}

int security_services::read_private_enc_key(const CHARSTRING& p_certificate_id, OCTETSTRING& p_private_enc_key) const {
  return _security_db.get()->get_private_enc_key(std::string(static_cast<const char*>(p_certificate_id)), p_private_enc_key);
}