-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
keychain: ValidityPeriod implementation
- Loading branch information
Showing
11 changed files
with
297 additions
and
183 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,31 +1,162 @@ | ||
#ifndef NDNPH_KEYCHAIN_VALIDITY_PERIOD_HPP | ||
#define NDNPH_KEYCHAIN_VALIDITY_PERIOD_HPP | ||
|
||
#include "../tlv/encoder.hpp" | ||
#include "../an.hpp" | ||
#include "../tlv/ev-decoder.hpp" | ||
#include "../tlv/value.hpp" | ||
#include <time.h> | ||
|
||
namespace ndnph { | ||
namespace detail { | ||
|
||
/** @brief ValidityPeriod stub. */ | ||
class UtcTimezone | ||
{ | ||
public: | ||
UtcTimezone() | ||
{ | ||
const char* tz = getenv("TZ"); | ||
if (tz == nullptr) { | ||
m_tz[0] = '\0'; | ||
} else { | ||
strncpy(m_tz, tz, sizeof(m_tz)); | ||
} | ||
setenv("TZ", "UTC", 1); | ||
} | ||
|
||
~UtcTimezone() | ||
{ | ||
if (m_tz[0] != '\0') { | ||
setenv("TZ", m_tz, 1); | ||
} | ||
} | ||
|
||
private: | ||
char m_tz[64]; | ||
}; | ||
|
||
} // namespace ndnph | ||
|
||
/** @brief ValidityPeriod of a certificate. */ | ||
class ValidityPeriod | ||
{ | ||
public: | ||
/** @brief Get a very long ValidityPeriod. */ | ||
static ValidityPeriod getMax() | ||
{ | ||
return ValidityPeriod(540109800, 253402300799); | ||
} | ||
|
||
ValidityPeriod() = default; | ||
|
||
ValidityPeriod(time_t notBefore, time_t notAfter) | ||
: notBefore(notBefore) | ||
, notAfter(notAfter) | ||
{} | ||
|
||
/** @brief Determine whether the specified timestamp is within validity period. */ | ||
bool includes(time_t t) | ||
{ | ||
return notBefore <= t && t <= notAfter; | ||
} | ||
|
||
void encodeTo(Encoder& encoder) const | ||
{ | ||
const char* stubNotBefore = "20200212T000000"; | ||
const char* stubNotAfter = "20201030T235959"; | ||
encoder.prependTlv( | ||
TT::ValidityPeriod, | ||
[=](Encoder& encoder) { | ||
[this](Encoder& encoder) { | ||
char buf[TIMESTAMP_BUFLEN]; | ||
printTimestamp(buf, notBefore); | ||
encoder.prependTlv(TT::NotBefore, | ||
tlv::Value(reinterpret_cast<const uint8_t*>(stubNotBefore), 15)); | ||
tlv::Value(reinterpret_cast<const uint8_t*>(buf), TIMESTAMP_LEN)); | ||
}, | ||
[=](Encoder& encoder) { | ||
[this](Encoder& encoder) { | ||
char buf[TIMESTAMP_BUFLEN]; | ||
printTimestamp(buf, notAfter); | ||
encoder.prependTlv(TT::NotAfter, | ||
tlv::Value(reinterpret_cast<const uint8_t*>(stubNotAfter), 15)); | ||
tlv::Value(reinterpret_cast<const uint8_t*>(buf), TIMESTAMP_LEN)); | ||
}); | ||
} | ||
|
||
bool decodeFrom(const Decoder::Tlv& input) | ||
{ | ||
return EvDecoder::decode(input, { TT::ValidityPeriod }, | ||
EvDecoder::def<TT::NotBefore>([this](const Decoder::Tlv& d) { | ||
return decodeTimestamp(d, ¬Before); | ||
}), | ||
EvDecoder::def<TT::NotAfter>([this](const Decoder::Tlv& d) { | ||
return decodeTimestamp(d, ¬After); | ||
})); | ||
} | ||
|
||
private: | ||
static constexpr size_t TIMESTAMP_LEN = 15; | ||
static constexpr size_t TIMESTAMP_BUFLEN = TIMESTAMP_LEN + 1; | ||
|
||
static const char* getTimestampFormat() | ||
{ | ||
return "%04d%02d%02dT%02d%02d%02d"; | ||
} | ||
|
||
static void printTimestamp(char buf[TIMESTAMP_BUFLEN], time_t t) | ||
{ | ||
struct tm* m = gmtime(&t); | ||
if (m == nullptr) { | ||
memset(buf, 0, TIMESTAMP_BUFLEN); | ||
return; | ||
} | ||
snprintf(buf, TIMESTAMP_BUFLEN, getTimestampFormat(), 1900 + m->tm_year, 1 + m->tm_mon, | ||
m->tm_mday, m->tm_hour, m->tm_min, m->tm_sec); | ||
} | ||
|
||
static bool decodeTimestamp(const Decoder::Tlv& d, time_t* v) | ||
{ | ||
if (d.length != TIMESTAMP_LEN) { | ||
return false; | ||
} | ||
|
||
char buf[TIMESTAMP_BUFLEN]; | ||
std::copy_n(d.value, TIMESTAMP_LEN, buf); | ||
buf[TIMESTAMP_LEN] = '\0'; | ||
|
||
struct tm m = {}; | ||
if (sscanf(buf, getTimestampFormat(), &m.tm_year, &m.tm_mon, &m.tm_mday, &m.tm_hour, &m.tm_min, | ||
&m.tm_sec) != 6) { | ||
return false; | ||
} | ||
m.tm_year -= 1900; | ||
m.tm_mon -= 1; | ||
|
||
detail::UtcTimezone useUtc; | ||
*v = mktime(&m); | ||
return *v >= 0; | ||
} | ||
|
||
public: | ||
/** @brief NotBefore field in seconds since Unix epoch. */ | ||
time_t notBefore = 0; | ||
|
||
/** @brief NotAfter field in seconds since Unix epoch. */ | ||
time_t notAfter = 0; | ||
}; | ||
|
||
inline bool | ||
operator==(const ValidityPeriod& lhs, const ValidityPeriod& rhs) | ||
{ | ||
return lhs.notBefore == rhs.notBefore && lhs.notAfter == rhs.notAfter; | ||
} | ||
|
||
NDNPH_DECLARE_NE(ValidityPeriod, inline) | ||
|
||
/** @brief Compute the intersection of two ValidityPeriods. */ | ||
inline ValidityPeriod | ||
operator&&(const ValidityPeriod& lhs, const ValidityPeriod& rhs) | ||
{ | ||
ValidityPeriod intersection; | ||
intersection.notBefore = std::max(lhs.notBefore, rhs.notBefore); | ||
intersection.notAfter = std::min(lhs.notAfter, rhs.notAfter); | ||
return intersection; | ||
} | ||
|
||
} // namespace ndnph | ||
|
||
#endif // NDNPH_KEYCHAIN_VALIDITY_PERIOD_HPP |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
#include "ndnph/keychain/validity-period.hpp" | ||
|
||
#include "test-common.hpp" | ||
|
||
namespace ndnph { | ||
namespace { | ||
|
||
TEST(ValidityPeriod, Normal) | ||
{ | ||
auto wire = test::fromHex("FD00FD26" | ||
"FD00FE0F 323031383131313354303835383439" // 20181113T085849 | ||
"FD00FF0F 323032303130313154313633383033" // 20201011T163803 | ||
); | ||
ValidityPeriod vp; | ||
vp.notBefore = 1542099529; | ||
vp.notAfter = 1602434283; | ||
{ | ||
StaticRegion<1024> region; | ||
Encoder encoder(region); | ||
bool ok = encoder.prepend(vp); | ||
ASSERT_TRUE(ok); | ||
EXPECT_THAT(std::vector<uint8_t>(encoder.begin(), encoder.end()), g::ElementsAreArray(wire)); | ||
} | ||
|
||
ValidityPeriod decoded; | ||
ASSERT_TRUE(Decoder(wire.data(), wire.size()).decode(decoded)); | ||
EXPECT_EQ(decoded.notBefore, 1542099529); | ||
EXPECT_EQ(decoded.notAfter, 1602434283); | ||
} | ||
|
||
TEST(ValidityPeriod, DecodeBadLength) | ||
{ | ||
auto wire = test::fromHex("FD00FD25" | ||
"FD00FE0F 323031383131313354303835383439" // 20181113T085849 | ||
"FD00FF0E 3230323031303131543136333830" // 20201011T16380 | ||
); // NotAfter is missing one byte | ||
ValidityPeriod vp; | ||
EXPECT_FALSE(Decoder(wire.data(), wire.size()).decode(vp)); | ||
} | ||
|
||
TEST(ValidityPeriod, DecodeBadValue) | ||
{ | ||
auto wire = test::fromHex("FD00FD25" | ||
"FD00FE0F 323031383131313341303835383439" // 20181113A085849 | ||
"FD00FF0E 323032303130313154313633383033" // 20201011T163803 | ||
); // NotBefore has 'A' instead of 'T' | ||
ValidityPeriod vp; | ||
EXPECT_FALSE(Decoder(wire.data(), wire.size()).decode(vp)); | ||
} | ||
|
||
TEST(ValidityPeriod, Includes) | ||
{ | ||
ValidityPeriod vp(1542099529, 1602434283); | ||
EXPECT_FALSE(vp.includes(1083820612)); | ||
EXPECT_FALSE(vp.includes(1542099528)); | ||
EXPECT_TRUE(vp.includes(1542099529)); | ||
EXPECT_TRUE(vp.includes(1569790373)); | ||
EXPECT_TRUE(vp.includes(1602434283)); | ||
EXPECT_FALSE(vp.includes(1602434284)); | ||
EXPECT_FALSE(vp.includes(1927427784)); | ||
|
||
vp = ValidityPeriod(); | ||
EXPECT_FALSE(vp.includes(1083820612)); | ||
EXPECT_FALSE(vp.includes(1569790373)); | ||
EXPECT_FALSE(vp.includes(1927427784)); | ||
} | ||
|
||
TEST(ValidityPeriod, Intersect) | ||
{ | ||
ValidityPeriod vp1(1542099529, 1602434283); | ||
ValidityPeriod vp2(1543017600, 1609372800); | ||
EXPECT_EQ((vp1 && vp2).notBefore, 1543017600); | ||
EXPECT_EQ((vp1 && vp2).notAfter, 1602434283); | ||
|
||
ValidityPeriod vp0 = ValidityPeriod::getMax() && vp1 && vp2; | ||
EXPECT_EQ(vp0, ValidityPeriod(1543017600, 1602434283)); | ||
} | ||
|
||
} // namespace | ||
} // namespace ndnph |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
unittest_files = files( | ||
'app/ping.t.cpp','app/rdr.t.cpp','app/segment.t.cpp','core/region.t.cpp','core/simple-queue.t.cpp','face/face.t.cpp','face/transport.t.cpp','keychain/certificate.t.cpp','keychain/digest-key.t.cpp','keychain/ecdsa-key.t.cpp','packet/component.t.cpp','packet/convention.t.cpp','packet/data.t.cpp','packet/interest.t.cpp','packet/nack.t.cpp','packet/name.t.cpp','tlv/decoder.t.cpp','tlv/encoder.t.cpp','tlv/ev-decoder.t.cpp','tlv/nni.t.cpp','tlv/varnum.t.cpp' | ||
'app/ping.t.cpp','app/rdr.t.cpp','app/segment.t.cpp','core/region.t.cpp','core/simple-queue.t.cpp','face/face.t.cpp','face/transport.t.cpp','keychain/certificate.t.cpp','keychain/digest-key.t.cpp','keychain/ecdsa-key.t.cpp','keychain/validity-period.t.cpp','packet/component.t.cpp','packet/convention.t.cpp','packet/data.t.cpp','packet/interest.t.cpp','packet/nack.t.cpp','packet/name.t.cpp','tlv/decoder.t.cpp','tlv/encoder.t.cpp','tlv/ev-decoder.t.cpp','tlv/nni.t.cpp','tlv/varnum.t.cpp' | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.