From 0463e087ad2da84efe93e0ea919c5b6ac3fc3382 Mon Sep 17 00:00:00 2001 From: Burak Arslan Date: Sun, 16 Jul 2023 12:03:34 +0300 Subject: [PATCH 1/3] add EC cert test --- test/credential.cpp | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/test/credential.cpp b/test/credential.cpp index 34ba3b1c5..4c1a5fdcd 100644 --- a/test/credential.cpp +++ b/test/credential.cpp @@ -48,6 +48,40 @@ TEST_CASE("X509 Credential Depth 2") CHECK(x509.der_chain == x509_original.der_chain); } +TEST_CASE("X509 Credential EC certificates") +{ + // Chain is of depth 2 + const auto keydata = + from_hex("30770201010420e32d0df2b096edadd778b3e884e84b14454d02668d3ef9f81e7" + "d9425ca9acf82a00a06082a8648ce3d030107a144034200049c37d6e8722c509c" + "c71bfda2389d4d3f6da6088b605c8bd6bd6dde6ccf77d3aa8c4f205cc273ac47b" + "e9e353e43debf2ad9a226fe0ea7a11b5bb06eb5d932e045"); + const auto cert = from_hex( + "308201e230820187a00302010202045a49733d300a06082a8648ce3d040302307331133011" + "060a0992268993f22c6401191603636f6d31173015060a0992268993f22c64011916076d61" + "696c6f757331143012060a0992268993f22c640101130474657374312d302b060355040b13" + "2431313436386463622d663830342d346563362d616166362d363263623437333931333733" + "301e170d3233303731353136303135305a170d3233303831353136303135305a3044311330" + "11060a0992268993f22c6401191603636f6d31173015060a0992268993f22c64011916076d" + "61696c6f757331143012060a0992268993f22c6401011304746573743059301306072a8648" + "ce3d020106082a8648ce3d030107034200049c37d6e8722c509cc71bfda2389d4d3f6da608" + "8b605c8bd6bd6dde6ccf77d3aa8c4f205cc273ac47be9e353e43debf2ad9a226fe0ea7a11b" + "5bb06eb5d932e045a3383036300e0603551d0f0101ff0404030204f030160603551d250101" + "ff040c300a06082b06010505070301300c0603551d130101ff04023000300a06082a8648ce" + "3d0403020349003046022100d670fb29f08dd0bc5d81cd6258ade6a8e5b6a5f630b510272c" + "ffa8d77f79f24e022100d166a8ae636916c84e1d854def33a57549e06b5c1d2c5e4ea7a797" + "df74401531"); + + const std::vector der_in{ cert }; + + auto key = SignaturePrivateKey::parse( + mls::CipherSuite::ID::P256_AES128GCM_SHA256_P256, keydata); + + auto cred = Credential::x509(der_in); + auto x509 = cred.get(); + CHECK(x509.public_key() == key.public_key); +} + TEST_CASE("X509 Credential Depth 2 Marshal/Unmarshal") { // Chain is of depth 2 From d8262402c818cf5c24fb2febc9aa76c6c1dd2f53 Mon Sep 17 00:00:00 2001 From: Burak Arslan Date: Sun, 16 Jul 2023 15:04:18 +0300 Subject: [PATCH 2/3] Implement SignaturePrivateKey::parse_der --- include/mls/crypto.h | 1 + lib/hpke/include/hpke/signature.h | 3 +++ lib/hpke/src/group.cpp | 38 +++++++++++++++++++++++++++---- lib/hpke/src/group.h | 2 ++ lib/hpke/src/signature.cpp | 14 ++++++++++++ src/crypto.cpp | 10 ++++++++ test/credential.cpp | 2 +- 7 files changed, 65 insertions(+), 5 deletions(-) diff --git a/include/mls/crypto.h b/include/mls/crypto.h index ab507ebbf..8f2c23c21 100644 --- a/include/mls/crypto.h +++ b/include/mls/crypto.h @@ -223,6 +223,7 @@ struct SignaturePrivateKey { static SignaturePrivateKey generate(CipherSuite suite); static SignaturePrivateKey parse(CipherSuite suite, const bytes& data); + static SignaturePrivateKey parse_der(CipherSuite suite, const bytes& data); static SignaturePrivateKey derive(CipherSuite suite, const bytes& secret); SignaturePrivateKey() = default; diff --git a/lib/hpke/include/hpke/signature.h b/lib/hpke/include/hpke/signature.h index 8ee0b39ba..979a54cfc 100644 --- a/lib/hpke/include/hpke/signature.h +++ b/lib/hpke/include/hpke/signature.h @@ -50,6 +50,9 @@ struct Signature virtual std::unique_ptr deserialize_private( const bytes& skm) const; + virtual std::unique_ptr deserialize_private_der( + const bytes& der) const; + virtual bytes sign(const bytes& data, const PrivateKey& sk) const = 0; virtual bool verify(const bytes& data, const bytes& sig, diff --git a/lib/hpke/src/group.cpp b/lib/hpke/src/group.cpp index 5afcd0250..cbac55575 100644 --- a/lib/hpke/src/group.cpp +++ b/lib/hpke/src/group.cpp @@ -8,6 +8,7 @@ #include "openssl/ec.h" #include "openssl/evp.h" #include "openssl/obj_mac.h" +#include "openssl/pem.h" #if defined(WITH_OPENSSL3) #include "openssl/core_names.h" #include "openssl/param_build.h" @@ -526,14 +527,27 @@ struct ECKeyGroup : public EVPGroup #endif } + std::unique_ptr deserialize_private_der( + const bytes& der) const override + { + BIO* mem = BIO_new_mem_buf(der.data(), static_cast(der.size())); + if (!mem) { + throw openssl_error(); + } + EVP_PKEY* pkey = d2i_PrivateKey_bio(mem, NULL); + BIO_free(mem); + if (!pkey) { + throw openssl_error(); + } + + return std::make_unique(pkey); + } + private: int curve_nid; #if !defined(WITH_OPENSSL3) - EC_KEY* new_ec_key() const - { - return EC_KEY_new_by_curve_name(curve_nid); - } + EC_KEY* new_ec_key() const { return EC_KEY_new_by_curve_name(curve_nid); } static EVP_PKEY* to_pkey(EC_KEY* eckey) { @@ -651,6 +665,22 @@ struct RawKeyGroup : public EVPGroup return std::make_unique(pkey); } + std::unique_ptr deserialize_private_der( + const bytes& der) const override + { + BIO* mem = BIO_new_mem_buf(der.data(), static_cast(der.size())); + if (!mem) { + throw openssl_error(); + } + EVP_PKEY* pkey = d2i_PrivateKey_bio(mem, NULL); + BIO_free(mem); + if (!pkey) { + throw openssl_error(); + } + + return std::make_unique(pkey); + } + private: const int evp_type; diff --git a/lib/hpke/src/group.h b/lib/hpke/src/group.h index ace8d7a92..33d775c48 100644 --- a/lib/hpke/src/group.h +++ b/lib/hpke/src/group.h @@ -55,6 +55,8 @@ struct Group virtual bytes serialize_private(const PrivateKey& sk) const = 0; virtual std::unique_ptr deserialize_private( const bytes& skm) const = 0; + virtual std::unique_ptr deserialize_private_der( + const bytes& der) const = 0; virtual bytes dh(const PrivateKey& sk, const PublicKey& pk) const = 0; diff --git a/lib/hpke/src/signature.cpp b/lib/hpke/src/signature.cpp index a79cafeaa..05f30c1f8 100644 --- a/lib/hpke/src/signature.cpp +++ b/lib/hpke/src/signature.cpp @@ -7,6 +7,7 @@ #include "group.h" #include "rsa.h" #include +#include #include namespace hpke { @@ -89,6 +90,13 @@ struct GroupSignature : public Signature group.deserialize_private(skm).release()); } + std::unique_ptr deserialize_private_der( + const bytes& der) const override + { + return std::make_unique( + group.deserialize_private_der(der).release()); + } + bytes sign(const bytes& data, const Signature::PrivateKey& sk) const override { const auto& rsk = dynamic_cast(sk); @@ -188,6 +196,12 @@ Signature::deserialize_private(const bytes& /* unused */) const throw std::runtime_error("Not implemented"); } +std::unique_ptr +Signature::deserialize_private_der(const bytes&) const +{ + throw std::runtime_error("Not implemented"); +} + std::unique_ptr Signature::generate_rsa(size_t bits) { diff --git a/src/crypto.cpp b/src/crypto.cpp index 3236e0267..51a6518dd 100644 --- a/src/crypto.cpp +++ b/src/crypto.cpp @@ -402,6 +402,16 @@ SignaturePrivateKey::parse(CipherSuite suite, const bytes& data) return { data, pub_data }; } +SignaturePrivateKey +SignaturePrivateKey::parse_der(CipherSuite suite, const bytes& data) +{ + auto priv = suite.sig().deserialize_private_der(data); + auto pub = priv->public_key(); + auto pub_data = suite.sig().serialize(*pub); + auto priv_data = suite.sig().serialize_private(*priv); + return { priv_data, pub_data }; +} + SignaturePrivateKey SignaturePrivateKey::derive(CipherSuite suite, const bytes& secret) { diff --git a/test/credential.cpp b/test/credential.cpp index 4c1a5fdcd..4db0e5008 100644 --- a/test/credential.cpp +++ b/test/credential.cpp @@ -74,7 +74,7 @@ TEST_CASE("X509 Credential EC certificates") const std::vector der_in{ cert }; - auto key = SignaturePrivateKey::parse( + auto key = SignaturePrivateKey::parse_der( mls::CipherSuite::ID::P256_AES128GCM_SHA256_P256, keydata); auto cred = Credential::x509(der_in); From a9a161a6d1bdc8aff7dc3cbdb004917247c11fb9 Mon Sep 17 00:00:00 2001 From: Burak Arslan Date: Wed, 19 Jul 2023 11:21:18 +0300 Subject: [PATCH 3/3] add missing ICU dependency --- cmd/interop/CMakeLists.txt | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/cmd/interop/CMakeLists.txt b/cmd/interop/CMakeLists.txt index 9ea990712..a824ed4a3 100644 --- a/cmd/interop/CMakeLists.txt +++ b/cmd/interop/CMakeLists.txt @@ -38,6 +38,7 @@ find_package(OpenSSL 1.1 REQUIRED) find_package(Protobuf REQUIRED) find_package(gRPC CONFIG REQUIRED) find_package(gflags REQUIRED) +find_package(ICU REQUIRED COMPONENTS uc data) # mlspp set(CMAKE_EXPORT_PACKAGE_REGISTRY ON) @@ -50,7 +51,7 @@ find_package(nlohmann_json 3.2 REQUIRED) ### Protobuf generation ### -# Get the proto file from the interop repo +# Get the proto file from the interop repo include( ExternalProject ) find_package( Git REQUIRED ) set( MLS_IMPLEMENTATIONS_REPO_URL https://github.com/mlswg/mls-implementations.git ) @@ -99,7 +100,7 @@ file(GLOB_RECURSE BIN_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp") add_executable(${APP_NAME} ${BIN_SOURCES} ${PB_SRC} ${GRPC_SRC}) add_dependencies(${APP_NAME} mls-interop-extern) target_include_directories(${APP_NAME} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) -target_link_libraries(${APP_NAME} - gflags - gRPC::grpc++ protobuf::libprotobuf +target_link_libraries(${APP_NAME} + gflags ICU::uc ICU::data + gRPC::grpc++ protobuf::libprotobuf MLSPP::mlspp MLSPP::mls_vectors MLSPP::tls_syntax)