Skip to content

Commit

Permalink
Merge remote-tracking branch 'remotes/origin/master' into feature/sec…
Browse files Browse the repository at this point in the history
…urity_merge

# Conflicts:
#	vanetza/security/straight_verify_service.cpp
#	vanetza/security/straight_verify_service.hpp
#	vanetza/security/v3/certificate.cpp
#	vanetza/security/v3/certificate_cache.hpp
  • Loading branch information
khevessy committed Sep 12, 2024
2 parents 65c2406 + 08fcce4 commit 035e566
Show file tree
Hide file tree
Showing 17 changed files with 476 additions and 65 deletions.
2 changes: 2 additions & 0 deletions vanetza/asn1/asn1c_wrapper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ class asn1c_wrapper_common

asn1c_wrapper_common(asn_TYPE_descriptor_t& desc) :
m_struct(vanetza::asn1::allocate<asn1c_type>()), m_type(desc) {}
asn1c_wrapper_common(asn_TYPE_descriptor_t& desc, const T* ptr) :
m_struct(static_cast<T*>(copy(desc, ptr))), m_type(desc) {}
~asn1c_wrapper_common() { vanetza::asn1::free(m_type, m_struct); }

// copy semantics
Expand Down
30 changes: 30 additions & 0 deletions vanetza/security/ecc_point.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#include <vanetza/security/ecc_point.hpp>
#include <vanetza/security/ecdsa256.hpp>
#include <vanetza/security/public_key.hpp>
#include <boost/variant/apply_visitor.hpp>
#include <boost/variant/static_visitor.hpp>

Expand Down Expand Up @@ -53,5 +55,33 @@ std::size_t get_length(const EccPoint& point)
return boost::apply_visitor(visitor, point);
}

EccPoint compress_public_key(const PublicKey& public_key)
{
switch (public_key.compression)
{
case KeyCompression::NoCompression:
if (!public_key.y.empty() && public_key.y.back() & 0x01) {
return Compressed_Lsb_Y_1 {public_key.x };
} else {
return Compressed_Lsb_Y_0 {public_key.x };
}
case KeyCompression::Y0:
return Compressed_Lsb_Y_0 {public_key.x };
case KeyCompression::Y1:
return Compressed_Lsb_Y_1 {public_key.x };
default:
return Compressed_Lsb_Y_0 {};
}
}

EccPoint compress_public_key(const ecdsa256::PublicKey& public_key)
{
if (!public_key.y.empty() && public_key.y.back() & 0x01) {
return Compressed_Lsb_Y_1 { ByteBuffer { public_key.x.begin(), public_key.x.end() } };
} else {
return Compressed_Lsb_Y_0 { ByteBuffer { public_key.x.begin(), public_key.x.end() } };
}
}

} // namespace security
} // namespace vanetza
12 changes: 12 additions & 0 deletions vanetza/security/ecc_point.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ namespace vanetza
namespace security
{

// forward declarations
struct PublicKey;
namespace ecdsa256 { struct PublicKey; }

/// X_Coordinate_Only specified in TS 103 097 v1.2.1 in section 4.2.5
struct X_Coordinate_Only
{
Expand Down Expand Up @@ -58,6 +62,14 @@ std::size_t get_length(const EccPoint& ecc_point);
*/
ByteBuffer convert_for_signing(const EccPoint& ecc_point);

/**
* \brief Compressed ECC point from public key
* \param public_key
* \return compressed ECC point
*/
EccPoint compress_public_key(const PublicKey& public_key);
EccPoint compress_public_key(const ecdsa256::PublicKey& public_key);

} // namespace security
} // namespace vanetza

Expand Down
13 changes: 13 additions & 0 deletions vanetza/security/hashed_id.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
#include <boost/functional/hash.hpp>
#include <algorithm>
#include <cassert>
#include <iomanip>
#include <sstream>

namespace vanetza
{
Expand Down Expand Up @@ -30,6 +32,17 @@ HashedId8 create_hashed_id8(const Sha384Digest& digest)
return hashed;
}

std::string to_string(const vanetza::security::HashedId8& digest)
{
std::stringstream ss;
ss << std::hex << std::setfill('0');
for (uint8_t octet : digest)
{
ss << std::setw(2) << static_cast<unsigned>(octet);
}
return ss.str();
}

} // namespace security
} // namespace vanetza

Expand Down
3 changes: 3 additions & 0 deletions vanetza/security/hashed_id.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <array>
#include <cstdint>
#include <functional>
#include <string>

namespace vanetza
{
Expand All @@ -19,6 +20,8 @@ HashedId3 truncate(const HashedId8&);
HashedId8 create_hashed_id8(const Sha256Digest&);
HashedId8 create_hashed_id8(const Sha384Digest&);

std::string to_string(const vanetza::security::HashedId8&);

} // namespace security
} // namespace vanetza

Expand Down
32 changes: 30 additions & 2 deletions vanetza/security/straight_verify_service.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -469,8 +469,22 @@ VerifyConfirm StraightVerifyService::verify(const v3::SecuredMessage& msg)
v3::CertificateCache* m_cache;
} certificate_lookup_visitor(cert_cache);
auto signer_identifier = msg.signer_identifier();

// track "known" stations
auto maybe_digest = v3::get_certificate_id(signer_identifier);
if (m_context_v3.m_cert_cache && maybe_digest) {
bool was_unknown_station = m_context_v3.m_cert_cache->announce(*maybe_digest);
if (was_unknown_station && msg.its_aid() == aid::CA && m_context_v3.m_sign_policy) {
// CAM from unknown station received, add our certificate to next outgoing message
m_context_v3.m_sign_policy->request_certificate();
}
}

const v3::asn1::Certificate* certificate = boost::apply_visitor(certificate_lookup_visitor, signer_identifier);
if (!certificate) {
if (!certificate && maybe_digest) {
if (m_context_v3.m_sign_policy) {
m_context_v3.m_sign_policy->request_unrecognized_certificate(*maybe_digest);
}
confirm.report = VerificationReport::Signer_Certificate_Not_Found;
if (sign_policy) {
auto cert_hash = v3::get_certificate_id(signer_identifier);
Expand Down Expand Up @@ -542,8 +556,22 @@ VerifyConfirm StraightVerifyService::verify(const v3::SecuredMessage& msg)

confirm.its_aid = msg.its_aid();
confirm.permissions = v3::get_app_permissions(*cert, confirm.its_aid);
confirm.certificate_id = v3::get_certificate_id(signer_identifier);
confirm.certificate_id = maybe_digest;
confirm.report = VerificationReport::Success;

if (m_context_v3.m_cert_cache && confirm.certificate_id) {
bool already_cached = m_context_v3.m_cert_cache->lookup(*confirm.certificate_id) != nullptr;
if (!already_cached && confirm.its_aid == aid::CA && m_context_v3.m_sign_policy) {
// CAM from unknown station received, add our certificate to next outgoing message
m_context_v3.m_sign_policy->request_certificate();
}

// update certificate cache with received certificate
if (certificate && v3::contains_certificate(signer_identifier)) {
m_context_v3.m_cert_cache->store(v3::Certificate { *certificate });
}
}

return confirm;
}

Expand Down
1 change: 1 addition & 0 deletions vanetza/security/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ configure_gtest_directory(LINK_LIBRARIES Boost::boost security security_test)
add_gtest(Backend backend.cpp)
add_gtest(CamServiceSpecificPermissions cam_ssp.cpp)
add_gtest(Certificate certificate.cpp)
add_gtest(CertificateV3 certificate_v3.cpp)
add_gtest(CertificateCache certificate_cache.cpp)
add_gtest(DefaultCertificateValidator default_certificate_validator.cpp)
add_gtest(DummyVerifyService dummy_verify_service.cpp)
Expand Down
12 changes: 12 additions & 0 deletions vanetza/security/tests/certificate_v3.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#include <gtest/gtest.h>
#include <vanetza/security/v3/certificate.hpp>
#include <vanetza/security/v3/certificate_cache.hpp>

using namespace vanetza;
using namespace vanetza::security;

TEST(CertificateV3, cache)
{
v3::CertificateCache cache;
cache.store(v3::fake_certificate());
}
27 changes: 13 additions & 14 deletions vanetza/security/tests/public_key.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,48 +5,47 @@

using namespace vanetza;
using namespace vanetza::security;
using namespace vanetza::security::v2;
using namespace std;

PublicKey serialize(PublicKey key)
v2::PublicKey serialize(v2::PublicKey key)
{
std::stringstream stream;
OutputArchive oa(stream);
serialize(oa, key);

PublicKey deKey;
v2::PublicKey deKey;
InputArchive ia(stream);
deserialize(ia, deKey);
return deKey;
}

TEST(PublicKey, Field_Size)
{
EXPECT_EQ(32, field_size(PublicKeyAlgorithm::ECDSA_NISTP256_With_SHA256));
EXPECT_EQ(32, field_size(PublicKeyAlgorithm::ECIES_NISTP256));
EXPECT_EQ(32, field_size(v2::PublicKeyAlgorithm::ECDSA_NISTP256_With_SHA256));
EXPECT_EQ(32, field_size(v2::PublicKeyAlgorithm::ECIES_NISTP256));
}

TEST(PublicKey, ECIES_NISTP256)
{
ecies_nistp256 ecies;
v2::ecies_nistp256 ecies;
ecies.public_key = Uncompressed { random_byte_sequence(32, 1), random_byte_sequence(32, 2) };
ecies.supported_symm_alg = SymmetricAlgorithm::AES128_CCM;
PublicKey key = ecies;
ecies.supported_symm_alg = v2::SymmetricAlgorithm::AES128_CCM;
v2::PublicKey key = ecies;

PublicKey deKey = serialize(key);
v2::PublicKey deKey = serialize(key);
check(key, deKey);
EXPECT_EQ(PublicKeyAlgorithm::ECIES_NISTP256, get_type(deKey));
EXPECT_EQ(v2::PublicKeyAlgorithm::ECIES_NISTP256, get_type(deKey));
EXPECT_EQ(67, get_size(deKey));
}

TEST(PublicKey, ECDSA_NISTP256_With_SHA256)
{
ecdsa_nistp256_with_sha256 ecdsa;
v2::ecdsa_nistp256_with_sha256 ecdsa;
ecdsa.public_key = X_Coordinate_Only { random_byte_sequence(32, 1) };
PublicKey key = ecdsa;
v2::PublicKey key = ecdsa;

PublicKey deKey = serialize(key);
v2::PublicKey deKey = serialize(key);
check(key, deKey);
EXPECT_EQ(PublicKeyAlgorithm::ECDSA_NISTP256_With_SHA256, get_type(deKey));
EXPECT_EQ(v2::PublicKeyAlgorithm::ECDSA_NISTP256_With_SHA256, get_type(deKey));
EXPECT_EQ(34, get_size(deKey));
}
Loading

0 comments on commit 035e566

Please sign in to comment.