Skip to content

Commit

Permalink
[build] support mbedtls 3.x
Browse files Browse the repository at this point in the history
Support building with mbedtls 3.x which is required for different
platforms.
  • Loading branch information
wgtdkp committed Apr 2, 2024
1 parent f63ec73 commit e2f0041
Show file tree
Hide file tree
Showing 15 changed files with 373 additions and 71 deletions.
11 changes: 11 additions & 0 deletions include/commissioner/error.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#define OT_COMM_ERROR_HPP_

#include <memory>
#include <ostream>
#include <string>

#include <commissioner/defines.hpp>
Expand Down Expand Up @@ -272,6 +273,16 @@ inline bool operator!=(const ErrorCode &aErrorCode, const Error &aError)
return !(aErrorCode == aError);
}

/**
* Allows pretty-print in unit tests.
*
* See https://google.github.io/googletest/advanced.html#teaching-googletest-how-to-print-your-values
*/
inline void PrintTo(const Error &error, std::ostream *os)
{
*os << error.ToString();
}

} // namespace commissioner

} // namespace ot
Expand Down
72 changes: 66 additions & 6 deletions src/library/coap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -195,8 +195,7 @@ Error Message::AppendOption(OptionType aNumber, const OptionValue &aValue)
{
Error error;

VerifyOrExit(IsValidOption(aNumber, aValue),
error = ERROR_INVALID_ARGS("invalid CoAP option (number={})", aNumber));
VerifyOrExit(IsValidOption(aNumber, aValue), error = ERROR_INVALID_ARGS("invalid CoAP option {}", aNumber));

if (aNumber == OptionType::kUriPath)
{
Expand All @@ -219,7 +218,7 @@ Error Message::GetOption(std::string &aValue, OptionType aNumber) const
Error error;
auto option = GetOption(aNumber);

VerifyOrExit(option != nullptr, error = ERROR_NOT_FOUND("CoAP option (number={}) not found", aNumber));
VerifyOrExit(option != nullptr, error = ERROR_NOT_FOUND("CoAP option {} not found", aNumber));

aValue = option->GetStringValue();

Expand All @@ -232,7 +231,7 @@ Error Message::GetOption(uint32_t &aValue, OptionType aNumber) const
Error error;
auto option = GetOption(aNumber);

VerifyOrExit(option != nullptr, error = ERROR_NOT_FOUND("CoAP option (number={}) not found", aNumber));
VerifyOrExit(option != nullptr, error = ERROR_NOT_FOUND("CoAP option {} not found", aNumber));

aValue = option->GetUint32Value();

Expand All @@ -245,7 +244,7 @@ Error Message::GetOption(ByteArray &aValue, OptionType aNumber) const
Error error;
auto option = GetOption(aNumber);

VerifyOrExit(option != nullptr, error = ERROR_NOT_FOUND("CoAP option (number={}) not found", aNumber));
VerifyOrExit(option != nullptr, error = ERROR_NOT_FOUND("CoAP option {} not found", aNumber));

aValue = option->GetOpaqueValue();

Expand Down Expand Up @@ -355,7 +354,7 @@ Error Message::Serialize(OptionType aOptionNumber,
VerifyOrDie(utils::to_underlying(aOptionNumber) >= aLastOptionNumber);

VerifyOrExit(IsValidOption(aOptionNumber, aOptionValue),
error = ERROR_INVALID_ARGS("option (number={}) is not valid", aOptionNumber));
error = ERROR_INVALID_ARGS("option {} is not valid", aOptionNumber));

length = 1;
length += delta < kOption1ByteExtension ? 0 : (delta < kOption2ByteExtension ? 1 : 2);
Expand Down Expand Up @@ -1287,3 +1286,64 @@ std::string Message::GetRequestUri(void) const
} // namespace commissioner

} // namespace ot

auto fmt::formatter<ot::commissioner::coap::OptionType>::format(ot::commissioner::coap::OptionType optionType,
format_context &ctx) -> decltype(ctx.out())
{
using ot::commissioner::coap::OptionType;
string_view name;
switch (optionType)
{
case OptionType::kIfMatch:
name = "kIfMatch";
break;
case OptionType::kUriHost:
name = "kUriHost";
break;
case OptionType::kETag:
name = "kETag";
break;
case OptionType::kIfNonMatch:
name = "kIfNonMatch";
break;
case OptionType::kObserve:
name = "kObserve";
break;
case OptionType::kUriPort:
name = "kUriPort";
break;
case OptionType::kLocationPath:
name = "kLocationPath";
break;
case OptionType::kUriPath:
name = "kUriPath";
break;
case OptionType::kContentFormat:
name = "kContentFormat";
break;
case OptionType::kMaxAge:
name = "kMaxAge";
break;
case OptionType::kUriQuery:
name = "kUriQuery";
break;
case OptionType::kAccept:
name = "kAccept";
break;
case OptionType::kLocationQuery:
name = "kLocationQuery";
break;
case OptionType::kProxyUri:
name = "kProxyUri";
break;
case OptionType::kProxyScheme:
name = "kProxyScheme";
break;
case OptionType::kSize1:
name = "kSize1";
break;
default:
name = "unknown";
}
return formatter<string_view>::format(name, ctx);
}
8 changes: 8 additions & 0 deletions src/library/coap.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@
#include <queue>
#include <set>

#include <fmt/format.h>

#include <commissioner/defines.hpp>
#include <commissioner/error.hpp>

Expand Down Expand Up @@ -781,4 +783,10 @@ class Coap

} // namespace ot

/** Makes `OptionType` formattable as a string. */
template <> struct fmt::formatter<ot::commissioner::coap::OptionType> : formatter<string_view>
{
auto format(ot::commissioner::coap::OptionType optionType, format_context &ctx) -> decltype(ctx.out());
};

#endif // OT_COMM_LIBRARY_COAP_HPP_
11 changes: 6 additions & 5 deletions src/library/cose.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
*/

#if OT_COMM_CONFIG_CCM_ENABLE
#define MBEDTLS_ALLOW_PRIVATE_ACCESS

#include "library/cose.hpp"

Expand Down Expand Up @@ -293,7 +294,7 @@ Error MakeCoseKey(ByteArray &aEncodedCoseKey, const mbedtls_pk_context &aKey, co
SuccessOrExit(error = coseKey.Put(kKeyType, kKeyTypeEC2));

// Cose key EC2 curve
switch (eckey->grp.id)
switch (eckey->MBEDTLS_PRIVATE(grp.id))
{
case MBEDTLS_ECP_DP_SECP256R1:
ec2Curve = kKeyEC2CurveP256;
Expand All @@ -310,23 +311,23 @@ Error MakeCoseKey(ByteArray &aEncodedCoseKey, const mbedtls_pk_context &aKey, co
SuccessOrExit(error = coseKey.Put(kKeyEC2Curve, ec2Curve));

// Cose key EC2 X
if (int fail = mbedtls_mpi_write_binary(&eckey->Q.X, xPoint, sizeof(xPoint)))
if (int fail = mbedtls_mpi_write_binary(&eckey->MBEDTLS_PRIVATE(Q.MBEDTLS_PRIVATE(X)), xPoint, sizeof(xPoint)))
{
ExitNow(error = ErrorFromMbedtlsError(fail));
}

// 'mbedtls_mpi_write_binary' writes to the end of buffer
xLength = mbedtls_mpi_size(&eckey->Q.X);
xLength = mbedtls_mpi_size(&eckey->MBEDTLS_PRIVATE(Q.X));
SuccessOrExit(error = coseKey.Put(kKeyEC2X, xPoint + sizeof(xPoint) - xLength, xLength));

// TODO(wgtdkp): handle the situation that Y point is not presented.
// Cose key EC2 Y
if (int fail = mbedtls_mpi_write_binary(&eckey->Q.Y, yPoint, sizeof(yPoint)))
if (int fail = mbedtls_mpi_write_binary(&eckey->MBEDTLS_PRIVATE(Q.Y), yPoint, sizeof(yPoint)))
{
ExitNow(error = ErrorFromMbedtlsError(fail));
}

yLength = mbedtls_mpi_size(&eckey->Q.Y);
yLength = mbedtls_mpi_size(&eckey->MBEDTLS_PRIVATE(Q.MBEDTLS_PRIVATE(Y)));
SuccessOrExit(error = coseKey.Put(kKeyEC2Y, yPoint + sizeof(yPoint) - yLength, yLength));

SuccessOrExit(error = coseKey.Serialize(encodedCoseKey, encodedCoseKeyLength, sizeof(encodedCoseKey)));
Expand Down
29 changes: 20 additions & 9 deletions src/library/cose_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,20 @@ static const char kPrivateKey[] = "-----BEGIN PRIVATE KEY-----\r\n"
"Xvr27euqi54WCMXJEMk6IIaPyFBNNw8bJvqXWfZ5g7t4hj7amsvqUST2\r\n"
"-----END PRIVATE KEY-----\r\n";

static Error ParsePublicKey(mbedtls_pk_context &aPublicKey, const ByteArray &aCert)
{
TokenManager tokenManager{event_base_new()};

return tokenManager.ParsePublicKey(aPublicKey, aCert);
}

static Error ParsePrivateKey(mbedtls_pk_context &aPrivateKey, const ByteArray &aPrivateKeyRaw)
{
TokenManager tokenManager{event_base_new()};

return tokenManager.ParsePrivateKey(aPrivateKey, aPrivateKeyRaw);
}

TEST(CoseTest, CoseSignAndVerify_SignWithoutExternalData)
{
ByteArray content{1, 2, 3, 4, 5, 6};
Expand All @@ -76,10 +90,9 @@ TEST(CoseTest, CoseSignAndVerify_SignWithoutExternalData)
mbedtls_pk_init(&publicKey);
mbedtls_pk_init(&privateKey);

EXPECT_EQ(TokenManager::ParsePublicKey(publicKey, ByteArray{kCertificate, kCertificate + sizeof(kCertificate)}),
ErrorCode::kNone);
EXPECT_EQ(TokenManager::ParsePrivateKey(privateKey, ByteArray{kPrivateKey, kPrivateKey + sizeof(kPrivateKey)}),
EXPECT_EQ(ParsePublicKey(publicKey, ByteArray{kCertificate, kCertificate + sizeof(kCertificate)}),
ErrorCode::kNone);
EXPECT_EQ(ParsePrivateKey(privateKey, ByteArray{kPrivateKey, kPrivateKey + sizeof(kPrivateKey)}), ErrorCode::kNone);

ByteArray signature;
Sign1Message msg;
Expand Down Expand Up @@ -107,10 +120,9 @@ TEST(CoseTest, CoseSignAndVerify_SignWithExternalData)
mbedtls_pk_init(&publicKey);
mbedtls_pk_init(&privateKey);

EXPECT_EQ(TokenManager::ParsePublicKey(publicKey, ByteArray{kCertificate, kCertificate + sizeof(kCertificate)}),
ErrorCode::kNone);
EXPECT_EQ(TokenManager::ParsePrivateKey(privateKey, ByteArray{kPrivateKey, kPrivateKey + sizeof(kPrivateKey)}),
EXPECT_EQ(ParsePublicKey(publicKey, ByteArray{kCertificate, kCertificate + sizeof(kCertificate)}),
ErrorCode::kNone);
EXPECT_EQ(ParsePrivateKey(privateKey, ByteArray{kPrivateKey, kPrivateKey + sizeof(kPrivateKey)}), ErrorCode::kNone);

ByteArray signature;
Sign1Message msg;
Expand Down Expand Up @@ -140,10 +152,9 @@ TEST(CoseTest, CoseSignAndVerify_KeyConstruction)
mbedtls_pk_init(&publicKey);
mbedtls_pk_init(&privateKey);

EXPECT_EQ(TokenManager::ParsePublicKey(publicKey, ByteArray{kCertificate, kCertificate + sizeof(kCertificate)}),
ErrorCode::kNone);
EXPECT_EQ(TokenManager::ParsePrivateKey(privateKey, ByteArray{kPrivateKey, kPrivateKey + sizeof(kPrivateKey)}),
EXPECT_EQ(ParsePublicKey(publicKey, ByteArray{kCertificate, kCertificate + sizeof(kCertificate)}),
ErrorCode::kNone);
EXPECT_EQ(ParsePrivateKey(privateKey, ByteArray{kPrivateKey, kPrivateKey + sizeof(kPrivateKey)}), ErrorCode::kNone);

ByteArray keyId = {};
ByteArray encodedCoseKey;
Expand Down
Loading

0 comments on commit e2f0041

Please sign in to comment.