From 2058c524ec6cc7d966d19545f056211ee33a7482 Mon Sep 17 00:00:00 2001 From: Pichi Date: Sun, 15 Aug 2021 12:45:57 -0600 Subject: [PATCH 1/3] Be compatible with mbedtls 3.0.0 - MBEDTLS_VERSION_STRING macros is moved from version.h to build_info.h - mbedtls_xxx_ret functions are rename to mbedtls_xxx - RC4 and Blowfish are deprecated --- cmake/FindMbedTLS.cmake | 8 ++++- include/pichi/crypto/hash.hpp | 15 ++++++++++ include/pichi/crypto/stream.hpp | 15 ++++++++-- src/crypto/stream.cpp | 52 +++++++++++++++++++-------------- src/net/adapter.cpp | 4 +++ src/net/ssstream.cpp | 4 +++ test/cryptogram.cpp | 46 ++++++++++++++++------------- test/ss.cpp | 2 ++ 8 files changed, 100 insertions(+), 46 deletions(-) diff --git a/cmake/FindMbedTLS.cmake b/cmake/FindMbedTLS.cmake index 474ab62..ff9a127 100644 --- a/cmake/FindMbedTLS.cmake +++ b/cmake/FindMbedTLS.cmake @@ -4,7 +4,13 @@ find_library(MbedTLS_LIBRARY NAMES mbedtls libmbedtls) find_library(MbedTLS_CRYPTO_LIBRARY NAMES mbedcrypto libmbedcrypto) if (MbedTLS_INCLUDE_DIRS) - file(STRINGS "${MbedTLS_INCLUDE_DIRS}/mbedtls/version.h" version_line + find_file(has_build_info "build_info.h" PATHS "${MbedTLS_INCLUDE_DIRS}/mbedtls") + if (has_build_info) + set(ver_file "${MbedTLS_INCLUDE_DIRS}/mbedtls/build_info.h") + else () + set(ver_file "${MbedTLS_INCLUDE_DIRS}/mbedtls/version.h") + endif () + file(STRINGS "${ver_file}" version_line REGEX "^#define[\t ]+MBEDTLS_VERSION_STRING[\t ]+\".*\"") if (version_line) string(REGEX REPLACE "^#define[\t ]+MBEDTLS_VERSION_STRING[\t ]+\"(.*)\"" diff --git a/include/pichi/crypto/hash.hpp b/include/pichi/crypto/hash.hpp index 109de9f..cc6fc3a 100644 --- a/include/pichi/crypto/hash.hpp +++ b/include/pichi/crypto/hash.hpp @@ -8,6 +8,21 @@ #include #include +#if MBEDTLS_VERSION_MAJOR >= 3 +#define mbedtls_md5_starts_ret mbedtls_md5_starts +#define mbedtls_sha1_starts_ret mbedtls_sha1_starts +#define mbedtls_sha256_starts_ret mbedtls_sha256_starts +#define mbedtls_sha512_starts_ret mbedtls_sha512_starts +#define mbedtls_md5_update_ret mbedtls_md5_update +#define mbedtls_sha1_update_ret mbedtls_sha1_update +#define mbedtls_sha256_update_ret mbedtls_sha256_update +#define mbedtls_sha512_update_ret mbedtls_sha512_update +#define mbedtls_md5_finish_ret mbedtls_md5_finish +#define mbedtls_sha1_finish_ret mbedtls_sha1_finish +#define mbedtls_sha256_finish_ret mbedtls_sha256_finish +#define mbedtls_sha512_finish_ret mbedtls_sha512_finish +#endif // MBEDTLS_VERSION_MAJOR >= 3 + namespace pichi::crypto { // TODO use lambda if compiler supports diff --git a/include/pichi/crypto/stream.hpp b/include/pichi/crypto/stream.hpp index 5ca831b..d82219e 100644 --- a/include/pichi/crypto/stream.hpp +++ b/include/pichi/crypto/stream.hpp @@ -4,25 +4,34 @@ #include #include #include -#include -#include #include #include #include #include +#if MBEDTLS_VERSION_MAJOR < 3 +#include +#include +#endif // MBEDTLS_VERSION_MAJOR < 3 + namespace pichi::crypto { template using StreamContext = std::conditional_t< +#if MBEDTLS_VERSION_MAJOR < 3 detail::isArc(), mbedtls_arc4_context, std::conditional_t< detail::isBlowfish(), mbedtls_blowfish_context, std::conditional_t< +#endif // MBEDTLS_VERSION_MAJOR < 3 detail::isAesCtr() || detail::isAesCfb(), mbedtls_aes_context, std::conditional_t(), mbedtls_camellia_context, std::conditional_t(), - std::array>, void>>>>>; + std::array>, void>>> +#if MBEDTLS_VERSION_MAJOR < 3 + >> +#endif // MBEDTLS_VERSION_MAJOR < 3 + ; template inline constexpr size_t BLK_SIZE = detail::isAesCtr() ? 16 : 0; diff --git a/src/crypto/stream.cpp b/src/crypto/stream.cpp index e4110e5..96e1291 100644 --- a/src/crypto/stream.cpp +++ b/src/crypto/stream.cpp @@ -124,17 +124,7 @@ static size_t encrypt(StreamContext& ctx, size_t offset, ConstBuffer= IV_SIZE + BLK_SIZE, PichiError::CRYPTO_ERROR); - if constexpr (detail::isArc()) { - assertTrue(mbedtls_arc4_crypt(&ctx, plain.size(), plain.data(), cipher.data()) == 0, - PichiError::CRYPTO_ERROR); - offset += plain.size(); - } - else if constexpr (detail::isBlowfish()) { - assertTrue(mbedtls_blowfish_crypt_cfb64(&ctx, MBEDTLS_BLOWFISH_ENCRYPT, plain.size(), &offset, - iv.data(), plain.data(), cipher.data()) == 0, - PichiError::CRYPTO_ERROR); - } - else if constexpr (detail::isAesCtr()) { + if constexpr (detail::isAesCtr()) { assertTrue(mbedtls_aes_crypt_ctr(&ctx, plain.size(), &offset, iv.data(), iv.data() + IV_SIZE, plain.data(), cipher.data()) == 0, PichiError::CRYPTO_ERROR); @@ -158,6 +148,18 @@ static size_t encrypt(StreamContext& ctx, size_t offset, ConstBuffer()) { + assertTrue(mbedtls_arc4_crypt(&ctx, plain.size(), plain.data(), cipher.data()) == 0, + PichiError::CRYPTO_ERROR); + offset += plain.size(); + } + else if constexpr (detail::isBlowfish()) { + assertTrue(mbedtls_blowfish_crypt_cfb64(&ctx, MBEDTLS_BLOWFISH_ENCRYPT, plain.size(), &offset, + iv.data(), plain.data(), cipher.data()) == 0, + PichiError::CRYPTO_ERROR); + } +#endif // MBEDTLS_VERSION_MAJOR < 3 else static_assert(detail::DependentFalse::value); return offset; @@ -170,17 +172,7 @@ static size_t decrypt(StreamContext& ctx, size_t offset, ConstBuffer= cipher.size(), PichiError::CRYPTO_ERROR); assertTrue(iv.size() >= IV_SIZE + BLK_SIZE, PichiError::CRYPTO_ERROR); - if constexpr (detail::isArc()) { - assertTrue(mbedtls_arc4_crypt(&ctx, cipher.size(), cipher.data(), plain.data()) == 0, - PichiError::CRYPTO_ERROR); - offset += cipher.size(); - } - else if constexpr (detail::isBlowfish()) { - assertTrue(mbedtls_blowfish_crypt_cfb64(&ctx, MBEDTLS_BLOWFISH_DECRYPT, cipher.size(), &offset, - iv.data(), cipher.data(), plain.data()) == 0, - PichiError::CRYPTO_ERROR); - } - else if constexpr (detail::isAesCtr()) { + if constexpr (detail::isAesCtr()) { assertTrue(mbedtls_aes_crypt_ctr(&ctx, cipher.size(), &offset, iv.data(), iv.data() + IV_SIZE, cipher.data(), plain.data()) == 0, PichiError::CRYPTO_ERROR); @@ -204,6 +196,18 @@ static size_t decrypt(StreamContext& ctx, size_t offset, ConstBuffer()) { + assertTrue(mbedtls_arc4_crypt(&ctx, cipher.size(), cipher.data(), plain.data()) == 0, + PichiError::CRYPTO_ERROR); + offset += cipher.size(); + } + else if constexpr (detail::isBlowfish()) { + assertTrue(mbedtls_blowfish_crypt_cfb64(&ctx, MBEDTLS_BLOWFISH_DECRYPT, cipher.size(), &offset, + iv.data(), cipher.data(), plain.data()) == 0, + PichiError::CRYPTO_ERROR); + } +#endif // MBEDTLS_VERSION_MAJOR < 3 else static_assert(detail::DependentFalse::value); return offset; @@ -240,8 +244,10 @@ size_t StreamEncryptor::encrypt(ConstBuffer plain, MutableBuffe return plain.size(); } +#if MBEDTLS_VERSION_MAJOR < 3 template class StreamEncryptor; template class StreamEncryptor; +#endif // MBEDTLS_VERSION_MAJOR < 3 template class StreamEncryptor; template class StreamEncryptor; template class StreamEncryptor; @@ -291,8 +297,10 @@ size_t StreamDecryptor::decrypt(ConstBuffer cipher, MutableBuff return cipher.size(); } +#if MBEDTLS_VERSION_MAJOR < 3 template class StreamDecryptor; template class StreamDecryptor; +#endif // MBEDTLS_VERSION_MAJOR < 3 template class StreamDecryptor; template class StreamDecryptor; template class StreamDecryptor; diff --git a/src/net/adapter.cpp b/src/net/adapter.cpp index d8895a5..693a25c 100644 --- a/src/net/adapter.cpp +++ b/src/net/adapter.cpp @@ -95,10 +95,12 @@ unique_ptr makeShadowsocksIngress(Socket&& s, vo::ShadowsocksOption con psk = {container, crypto::generateKey(option.method_, ConstBuffer{option.password_}, container)}; switch (option.method_) { +#if MBEDTLS_VERSION_MAJOR < 3 case CryptoMethod::RC4_MD5: return make_unique>(psk, forward(s)); case CryptoMethod::BF_CFB: return make_unique>(psk, forward(s)); +#endif // MBEDTLS_VERSION_MAJOR < 3 case CryptoMethod::AES_128_CTR: return make_unique>(psk, forward(s)); case CryptoMethod::AES_192_CTR: @@ -152,10 +154,12 @@ static unique_ptr makeShadowsocksEgress(vo::ShadowsocksOption const& opt auto psk = MutableBuffer{container, len}; switch (option.method_) { +#if MBEDTLS_VERSION_MAJOR < 3 case CryptoMethod::RC4_MD5: return make_unique>(psk, io); case CryptoMethod::BF_CFB: return make_unique>(psk, io); +#endif // MBEDTLS_VERSION_MAJOR < 3 case CryptoMethod::AES_128_CTR: return make_unique>(psk, io); case CryptoMethod::AES_192_CTR: diff --git a/src/net/ssstream.cpp b/src/net/ssstream.cpp index 410a2c0..a7d7ae8 100644 --- a/src/net/ssstream.cpp +++ b/src/net/ssstream.cpp @@ -100,8 +100,10 @@ void SSStreamAdapter::connect(Endpoint const& remote, ResolveRes send({plain, plen}, yield); } +#if MBEDTLS_VERSION_MAJOR < 3 template class SSStreamAdapter; template class SSStreamAdapter; +#endif // MBEDTLS_VERSION_MAJOR < 3 template class SSStreamAdapter; template class SSStreamAdapter; template class SSStreamAdapter; @@ -116,8 +118,10 @@ template class SSStreamAdapter; template class SSStreamAdapter; #ifdef BUILD_TEST +#if MBEDTLS_VERSION_MAJOR < 3 template class SSStreamAdapter; template class SSStreamAdapter; +#endif // MBEDTLS_VERSION_MAJOR < 3 template class SSStreamAdapter; template class SSStreamAdapter; template class SSStreamAdapter; diff --git a/test/cryptogram.cpp b/test/cryptogram.cpp index 1969c34..d39eaaa 100644 --- a/test/cryptogram.cpp +++ b/test/cryptogram.cpp @@ -55,6 +55,7 @@ template struct Ciphers { static vector const& IV; }; +#if MBEDTLS_VERSION_MAJOR < 3 template <> vector> const Ciphers::CIPHERS = { hex2bin("cd1695a36fbfb5270d59fcf7153e7dcf"), hex2bin("eca24c0e95c67b736c52e75d66355385"), @@ -88,6 +89,7 @@ vector> const Ciphers::CIPHERS = { hex2bin("985445eed87575ffd8f105c70fcc6db9"), hex2bin("cd8fd745369f58")}; template <> vector const& Ciphers::KEY = KeyIv<16>::KEY; template <> vector const& Ciphers::IV = KeyIv<8>::IV; +#endif // MBEDTLS_VERSION_MAJOR < 3 template <> vector> const Ciphers::CIPHERS = { @@ -442,26 +444,30 @@ vector const& Ciphers::KEY = Key template <> vector const& Ciphers::IV = KeyIv<32>::IV; -using Cases = - mpl::list, Ciphers, - Ciphers, Ciphers, - Ciphers, Ciphers, - Ciphers, Ciphers, - Ciphers, Ciphers, - Ciphers, Ciphers, - Ciphers, Ciphers, - Ciphers, Ciphers, - Ciphers, Ciphers, - Ciphers>; - -using StreamCases = - mpl::list, Ciphers, - Ciphers, Ciphers, - Ciphers, Ciphers, - Ciphers, Ciphers, - Ciphers, Ciphers, - Ciphers, Ciphers, - Ciphers, Ciphers>; +using Cases = mpl::list< +#if MBEDTLS_VERSION_MAJOR < 3 + Ciphers, Ciphers, +#endif // MBEDTLS_VERSION_MAJOR < 3 + Ciphers, Ciphers, + Ciphers, Ciphers, + Ciphers, Ciphers, + Ciphers, Ciphers, + Ciphers, Ciphers, + Ciphers, Ciphers, + Ciphers, Ciphers, + Ciphers, Ciphers, + Ciphers>; + +using StreamCases = mpl::list< +#if MBEDTLS_VERSION_MAJOR < 3 + Ciphers, Ciphers, +#endif // MBEDTLS_VERSION_MAJOR < 3 + Ciphers, Ciphers, + Ciphers, Ciphers, + Ciphers, Ciphers, + Ciphers, Ciphers, + Ciphers, Ciphers, + Ciphers, Ciphers>; BOOST_AUTO_TEST_SUITE(Cryptogram) diff --git a/test/ss.cpp b/test/ss.cpp index d70f59f..945a23e 100644 --- a/test/ss.cpp +++ b/test/ss.cpp @@ -27,7 +27,9 @@ using StreamAdapter = net::SSStreamAdapter; template using AeadAdapter = net::SSAeadAdapter; using Adapters = mpl::list< +#if MBEDTLS_VERSION_MAJOR < 3 StreamAdapter, StreamAdapter, +#endif // MBEDTLS_VERSION_MAJOR < 3 StreamAdapter, StreamAdapter, StreamAdapter, StreamAdapter, StreamAdapter, StreamAdapter, From 6e512d31c29ee10f83a294f8eaeb5563a18f8b56 Mon Sep 17 00:00:00 2001 From: Pichi Date: Mon, 2 Aug 2021 00:24:11 -1000 Subject: [PATCH 2/3] Throw SEMANTIC_ERROR exception while creating deprecated shadowsocks adapter --- include/pichi/vo/messages.hpp | 1 + src/net/adapter.cpp | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/include/pichi/vo/messages.hpp b/include/pichi/vo/messages.hpp index 57b6e43..08b96c7 100644 --- a/include/pichi/vo/messages.hpp +++ b/include/pichi/vo/messages.hpp @@ -44,6 +44,7 @@ inline std::string_view const TOO_LONG_NAME_PASSWORD = "Name or password is too inline std::string_view const DUPLICATED_ITEMS = "Duplicated items"; inline std::string_view const NOT_IMPLEMENTED = "Not implemented"; +inline std::string_view const DEPRECATED_METHOD = "rc4-md5 & bf-cfb are deprecated"; } // namespace pichi::vo::msg diff --git a/src/net/adapter.cpp b/src/net/adapter.cpp index 693a25c..2698464 100644 --- a/src/net/adapter.cpp +++ b/src/net/adapter.cpp @@ -100,6 +100,10 @@ unique_ptr makeShadowsocksIngress(Socket&& s, vo::ShadowsocksOption con return make_unique>(psk, forward(s)); case CryptoMethod::BF_CFB: return make_unique>(psk, forward(s)); +#else // MBEDTLS_VERSION_MAJOR < 3 + case CryptoMethod::RC4_MD5: + case CryptoMethod::BF_CFB: + fail(PichiError::SEMANTIC_ERROR, vo::msg::DEPRECATED_METHOD); #endif // MBEDTLS_VERSION_MAJOR < 3 case CryptoMethod::AES_128_CTR: return make_unique>(psk, forward(s)); @@ -159,6 +163,10 @@ static unique_ptr makeShadowsocksEgress(vo::ShadowsocksOption const& opt return make_unique>(psk, io); case CryptoMethod::BF_CFB: return make_unique>(psk, io); +#else // MBEDTLS_VERSION_MAJOR < 3 + case CryptoMethod::RC4_MD5: + case CryptoMethod::BF_CFB: + fail(PichiError::SEMANTIC_ERROR, vo::msg::DEPRECATED_METHOD); #endif // MBEDTLS_VERSION_MAJOR < 3 case CryptoMethod::AES_128_CTR: return make_unique>(psk, io); From af3be7d037a3b2d879ffb5da2bb6673101ffc164 Mon Sep 17 00:00:00 2001 From: Pichi Date: Sun, 25 Jul 2021 08:59:54 +1100 Subject: [PATCH 3/3] Fix some parsing/serializing errors which are not corresponding to API specification - 'credential' should be 'credentials' in vo::Ingress key - 'auto' should be 'none' for the security value of VMESS adapter - Fix shadowsocks examples --- include/pichi/vo/keys.hpp | 4 ++-- schemas/examples/egress/ss.json | 2 +- schemas/examples/ingress/ss.json | 2 +- src/vo/ingress.cpp | 18 +++++++++--------- test/vo_ingress.cpp | 11 ++++++----- 5 files changed, 19 insertions(+), 18 deletions(-) diff --git a/include/pichi/vo/keys.hpp b/include/pichi/vo/keys.hpp index 1311f9f..c7f30a3 100644 --- a/include/pichi/vo/keys.hpp +++ b/include/pichi/vo/keys.hpp @@ -60,7 +60,7 @@ inline decltype(auto) LEAST_CONN = "least_conn"; namespace security { inline decltype(auto) AUTO = "auto"; -inline decltype(auto) NONE = "auto"; +inline decltype(auto) NONE = "none"; inline decltype(auto) CHACHA20_IETF_POLY1305 = "chacha20-ietf-poly1305"; inline decltype(auto) AES_128_GCM = "aes-128-gcm"; @@ -119,7 +119,7 @@ inline decltype(auto) TYPE = "type"; inline decltype(auto) BIND = "bind"; inline decltype(auto) OPTION = "option"; inline decltype(auto) TLS = "tls"; -inline decltype(auto) CREDENTIAL = "credential"; +inline decltype(auto) CREDENTIALS = "credentials"; inline decltype(auto) WEBSOCKET = "websocket"; } // namespace ingress diff --git a/schemas/examples/egress/ss.json b/schemas/examples/egress/ss.json index 727feac..f604a4d 100644 --- a/schemas/examples/egress/ss.json +++ b/schemas/examples/egress/ss.json @@ -4,7 +4,7 @@ "host": "ss.example.com", "port": 8388 }, - "ss": { + "option": { "password": "shadowsocks password", "method": "rc4-md5" } diff --git a/schemas/examples/ingress/ss.json b/schemas/examples/ingress/ss.json index 92ec562..3ebf018 100644 --- a/schemas/examples/ingress/ss.json +++ b/schemas/examples/ingress/ss.json @@ -10,7 +10,7 @@ "port": 8388 } ], - "ss": { + "option": { "method": "xchacha20-ietf-poly1305", "password": "shadowsocks password" } diff --git a/src/vo/ingress.cpp b/src/vo/ingress.cpp index ad9efb2..3644b5c 100644 --- a/src/vo/ingress.cpp +++ b/src/vo/ingress.cpp @@ -35,7 +35,7 @@ json::Value toJson(Ingress const& ingress, Allocator& alloc) case AdapterType::SOCKS5: if (ingress.tls_.has_value()) ret.AddMember(ingress::TLS, toJson(*ingress.tls_, alloc), alloc); if (ingress.credential_.has_value()) - ret.AddMember(ingress::CREDENTIAL, + ret.AddMember(ingress::CREDENTIALS, toJson(get(*ingress.credential_), alloc), alloc); break; case AdapterType::SS: @@ -48,14 +48,14 @@ json::Value toJson(Ingress const& ingress, Allocator& alloc) assertTrue(ingress.credential_.has_value()); ret.AddMember(ingress::OPTION, toJson(get(*ingress.opt_), alloc), alloc); ret.AddMember(ingress::TLS, toJson(*ingress.tls_, alloc), alloc); - ret.AddMember(ingress::CREDENTIAL, + ret.AddMember(ingress::CREDENTIALS, toJson(get(*ingress.credential_), alloc), alloc); if (ingress.websocket_.has_value()) ret.AddMember(ingress::WEBSOCKET, toJson(*ingress.websocket_, alloc), alloc); break; case AdapterType::VMESS: assertTrue(ingress.credential_.has_value()); - ret.AddMember(ingress::CREDENTIAL, + ret.AddMember(ingress::CREDENTIALS, toJson(get(*ingress.credential_), alloc), alloc); if (ingress.tls_.has_value()) ret.AddMember(ingress::TLS, toJson(*ingress.tls_, alloc), alloc); if (ingress.websocket_.has_value()) @@ -93,26 +93,26 @@ template <> Ingress parse(json::Value const& v) case AdapterType::HTTP: case AdapterType::SOCKS5: if (v.HasMember(ingress::TLS)) ingress.tls_ = parse(v[ingress::TLS]); - if (v.HasMember(ingress::CREDENTIAL)) - ingress.credential_ = parse(v[ingress::CREDENTIAL]); + if (v.HasMember(ingress::CREDENTIALS)) + ingress.credential_ = parse(v[ingress::CREDENTIALS]); break; case AdapterType::SS: assertTrue(v.HasMember(ingress::OPTION), PichiError::BAD_JSON, msg::MISSING_OPTION_FIELD); ingress.opt_ = parse(v[ingress::OPTION]); break; case AdapterType::TROJAN: - assertTrue(v.HasMember(ingress::CREDENTIAL), PichiError::BAD_JSON, msg::MISSING_CRED_FIELD); + assertTrue(v.HasMember(ingress::CREDENTIALS), PichiError::BAD_JSON, msg::MISSING_CRED_FIELD); assertTrue(v.HasMember(ingress::OPTION), PichiError::BAD_JSON, msg::MISSING_OPTION_FIELD); assertTrue(v.HasMember(ingress::TLS), PichiError::BAD_JSON, msg::MISSING_TLS_FIELD); - ingress.credential_ = parse(v[ingress::CREDENTIAL]); + ingress.credential_ = parse(v[ingress::CREDENTIALS]); ingress.opt_ = parse(v[ingress::OPTION]); ingress.tls_ = parse(v[ingress::TLS]); if (v.HasMember(ingress::WEBSOCKET)) ingress.websocket_ = parse(v[ingress::WEBSOCKET]); break; case AdapterType::VMESS: - assertTrue(v.HasMember(ingress::CREDENTIAL), PichiError::BAD_JSON, msg::MISSING_CRED_FIELD); - ingress.credential_ = parse(v[ingress::CREDENTIAL]); + assertTrue(v.HasMember(ingress::CREDENTIALS), PichiError::BAD_JSON, msg::MISSING_CRED_FIELD); + ingress.credential_ = parse(v[ingress::CREDENTIALS]); if (v.HasMember(ingress::TLS)) ingress.tls_ = parse(v[ingress::TLS]); if (v.HasMember(ingress::WEBSOCKET)) ingress.websocket_ = parse(v[ingress::WEBSOCKET]); diff --git a/test/vo_ingress.cpp b/test/vo_ingress.cpp index a9b5437..1221e91 100644 --- a/test/vo_ingress.cpp +++ b/test/vo_ingress.cpp @@ -100,7 +100,7 @@ template Value defaultIngressJson() ingress.AddMember(ingress::BIND, Value{kArrayType}, alloc); ingress[ingress::BIND].PushBack(toJson(DEFAULT_ENDPOINT, alloc), alloc); if constexpr (Trait::credential_ == Present::MANDATORY) - ingress.AddMember(ingress::CREDENTIAL, defaultCredentialJson(), + ingress.AddMember(ingress::CREDENTIALS, defaultCredentialJson(), alloc); if constexpr (Trait::option_ == Present::MANDATORY) ingress.AddMember(ingress::OPTION, defaultOptionJson(), alloc); @@ -188,7 +188,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(parse_Empty_Bind, Trait, AllAdapterTraits) BOOST_AUTO_TEST_CASE_TEMPLATE(parse_Mandatory_Fields, Trait, AllAdapterTraits) { if constexpr (Trait::credential_ == Present::MANDATORY) - verifyMandatoryField(ingress::CREDENTIAL); + verifyMandatoryField(ingress::CREDENTIALS); if constexpr (Trait::option_ == Present::MANDATORY) verifyMandatoryField(ingress::OPTION); if constexpr (Trait::tls_ == Present::MANDATORY) verifyMandatoryField(ingress::TLS); @@ -203,7 +203,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(parse_Optional_Fields, Trait, AllAdapterTraits) auto ingress = defaultIngress(); ingress.credential_ = defaultCredential(); BOOST_CHECK(parse(defaultIngressJson().AddMember( - ingress::CREDENTIAL, defaultCredentialJson(), alloc)) == ingress); + ingress::CREDENTIALS, defaultCredentialJson(), alloc)) == ingress); } if constexpr (Trait::option_ == Present::OPTIONAL) { using Option = typename Trait::Option; @@ -230,7 +230,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(parse_Unused_Fields, Trait, AllAdapterTraits) { auto json = defaultIngressJson(); if constexpr (Trait::credential_ == Present::UNUSED) - json.AddMember(ingress::CREDENTIAL, Value{kObjectType}, alloc); + json.AddMember(ingress::CREDENTIALS, Value{kObjectType}, alloc); if constexpr (Trait::option_ == Present::UNUSED) json.AddMember(ingress::OPTION, Value{kObjectType}, alloc); if constexpr (Trait::tls_ == Present::UNUSED) @@ -293,7 +293,8 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(toJson_Optional_Fields, Trait, AllAdapterTraits) if constexpr (Trait::credential_ == Present::OPTIONAL) { ingress.credential_ = defaultCredential(); - json.AddMember(ingress::CREDENTIAL, defaultCredentialJson(), alloc); + json.AddMember(ingress::CREDENTIALS, defaultCredentialJson(), + alloc); } if constexpr (Trait::option_ == Present::OPTIONAL) { ingress.opt_ = defaultOption();