Skip to content

Commit

Permalink
keychain: build certificate into Data::Signed type
Browse files Browse the repository at this point in the history
  • Loading branch information
yoursunny committed Jan 15, 2021
1 parent 660b0f4 commit d4abb12
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 83 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ Packet encoding and decoding
Transports

* UDP: unicast only
* libmemif

KeyChain

Expand Down
76 changes: 19 additions & 57 deletions src/ndnph/keychain/certificate.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -223,70 +223,32 @@ getValidity(const Data& data)
} // namespace certificate
namespace detail {

template<typename Signer>
class CertificateBuilder
template<typename Signer, typename Modify>
Data::Signed
buildCertificate(Region& region, const Name& name, const ValidityPeriod& validity,
const Signer& signer, const Modify& modify)
{
public:
template<typename Modify>
static CertificateBuilder<Signer> create(Region& region, const Name& name,
const ValidityPeriod& validity, const Signer& signer,
const Modify& modify)
{
CertificateBuilder<Signer> builder(region, signer);
if (!builder) {
return builder.reset();
}

Data& data = builder.m_data;
data.setName(certificate::toCertName(region, name));
data.setContentType(ContentType::Key);
data.setFreshnessPeriod(3600000);
bool ok = modify(data);
if (!ok) {
return builder.reset();
}

DSigInfo& si = builder.m_si;
{
Encoder encoder(region);
encoder.prepend(validity);
si.extensions = tlv::Value(encoder);
encoder.trim();
}
return builder;
}

explicit operator bool() const
{
return !!m_data;
auto data = region.create<Data>();
if (!data) {
return Data::Signed();
}
data.setName(certificate::toCertName(region, name));
data.setContentType(ContentType::Key);
data.setFreshnessPeriod(3600000);

void encodeTo(Encoder& encoder) const
DSigInfo si;
{
if (!m_data) {
encoder.setError();
} else {
m_data.sign(m_signer, m_si).encodeTo(encoder);
}
Encoder encoder(region);
encoder.prepend(validity);
si.extensions = tlv::Value(encoder);
encoder.trim();
}

private:
explicit CertificateBuilder(Region& region, const Signer& signer)
: m_data(region.create<Data>())
, m_signer(signer)
{}

CertificateBuilder<Signer>& reset()
{
m_data = Data();
return *this;
if (!modify(data)) {
return Data::Signed();
}

private:
Data m_data;
DSigInfo m_si;
const Signer& m_signer;
};
return data.sign(signer, std::move(si));
}

} // namespace detail
} // namespace ndnph
Expand Down
35 changes: 16 additions & 19 deletions src/ndnph/keychain/ec.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,24 +143,22 @@ class EcPublicKey : public PublicKey
* are kept alive.
*/
template<typename Signer>
detail::CertificateBuilder<Signer> buildCertificate(Region& region, const Name& name,
const ValidityPeriod& validity,
const Signer& signer) const
Data::Signed buildCertificate(Region& region, const Name& name, const ValidityPeriod& validity,
const Signer& signer) const
{
return detail::CertificateBuilder<Signer>::create(
region, name, validity, signer, [&](Data& data) {
auto spkiHdr = detail::getSpkiHeader();
size_t spkiLen = spkiHdr.size() + KeyLen::value;
uint8_t* spki = region.alloc(spkiLen);
if (spki == nullptr) {
return false;
}

auto pos = std::copy_n(spkiHdr.begin(), spkiHdr.size(), spki);
std::copy_n(m_raw, KeyLen::value, pos);
data.setContent(tlv::Value(spki, spkiLen));
return true;
});
return detail::buildCertificate(region, name, validity, signer, [&](Data& data) {
auto spkiHdr = detail::getSpkiHeader();
size_t spkiLen = spkiHdr.size() + KeyLen::value;
uint8_t* spki = region.alloc(spkiLen);
if (spki == nullptr) {
return false;
}

auto pos = std::copy_n(spkiHdr.begin(), spkiHdr.size(), spki);
std::copy_n(m_raw, KeyLen::value, pos);
data.setContent(tlv::Value(spki, spkiLen));
return true;
});
}

/**
Expand All @@ -173,8 +171,7 @@ class EcPublicKey : public PublicKey
* are kept alive.
*/
template<typename Signer>
detail::CertificateBuilder<Signer> selfSign(Region& region, const ValidityPeriod& validity,
const Signer& signer) const
Data::Signed selfSign(Region& region, const ValidityPeriod& validity, const Signer& signer) const
{
Name certName = certificate::makeCertName(region, getName(), certificate::getIssuerSelf());
return buildCertificate(region, certName, validity, signer);
Expand Down
14 changes: 7 additions & 7 deletions src/ndnph/keychain/validity-period.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class ValidityPeriod
/** @brief Get a very long ValidityPeriod. */
static ValidityPeriod getMax()
{
return ValidityPeriod(540109800, MaxTime::value);
return ValidityPeriod(540109800, MAX_TIME);
}

ValidityPeriod() = default;
Expand Down Expand Up @@ -88,8 +88,13 @@ class ValidityPeriod
}

private:
static constexpr time_t MAX_TIME =
sizeof(time_t) <= 4 ? std::numeric_limits<time_t>::max() : 253402300799;
static constexpr size_t TIMESTAMP_LEN = 15;
static constexpr size_t TIMESTAMP_BUFLEN = TIMESTAMP_LEN + 1;
static constexpr size_t ENCODE_LENGTH =
tlv::sizeofVarNum(TT::NotBefore) + tlv::sizeofVarNum(TIMESTAMP_LEN) + TIMESTAMP_LEN +
tlv::sizeofVarNum(TT::NotAfter) + tlv::sizeofVarNum(TIMESTAMP_LEN) + TIMESTAMP_LEN;

static const char* getTimestampFormat()
{
Expand Down Expand Up @@ -128,7 +133,7 @@ class ValidityPeriod
detail::UtcTimezone useUtc;
*v = mktime(&m);
if (sizeof(time_t) <= 4 && *v < 0 && (1900 + m.tm_year) >= 2038) {
*v = MaxTime::value;
*v = MAX_TIME;
}
return *v >= 0;
}
Expand All @@ -139,11 +144,6 @@ class ValidityPeriod

/** @brief NotAfter field in seconds since Unix epoch. */
time_t notAfter = 0;

private:
using MaxTime =
std::integral_constant<time_t,
sizeof(time_t) <= 4 ? std::numeric_limits<time_t>::max() : 253402300799>;
};

inline bool
Expand Down

0 comments on commit d4abb12

Please sign in to comment.