ndn-cxx: NDN C++ Library 0.9.0-33-g832ea91d
Loading...
Searching...
No Matches
validity-period.cpp
Go to the documentation of this file.
1/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2013-2025 Regents of the University of California.
4 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
6 *
7 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later version.
10 *
11 * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14 *
15 * You should have received copies of the GNU General Public License and GNU Lesser
16 * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17 * <http://www.gnu.org/licenses/>.
18 *
19 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
20 */
21
24
25namespace ndn::security {
26
27using boost::chrono::time_point_cast;
28
29constexpr size_t ISO_DATETIME_SIZE = 15;
30constexpr size_t NOT_BEFORE_OFFSET = 0;
31constexpr size_t NOT_AFTER_OFFSET = 1;
32
36{
37 return ValidityPeriod(now + validFrom, now + validUntil);
38}
39
41 : ValidityPeriod(time::system_clock::time_point() + 1_ns,
42 time::system_clock::time_point())
43{
44}
45
47 const time::system_clock::time_point& notAfter)
48 : m_notBefore(toTimePointCeil(notBefore))
49 , m_notAfter(toTimePointFloor(notAfter))
50{
51}
52
54{
55 wireDecode(block);
56}
57
58template<encoding::Tag TAG>
59size_t
61{
62 size_t totalLength = 0;
63
64 totalLength += prependStringBlock(encoder, tlv::NotAfter, time::toIsoString(m_notAfter));
65 totalLength += prependStringBlock(encoder, tlv::NotBefore, time::toIsoString(m_notBefore));
66
67 totalLength += encoder.prependVarNumber(totalLength);
68 totalLength += encoder.prependVarNumber(tlv::ValidityPeriod);
69 return totalLength;
70}
71
73
74const Block&
76{
77 if (m_wire.hasWire())
78 return m_wire;
79
80 EncodingEstimator estimator;
81 size_t estimatedSize = wireEncode(estimator);
82
83 EncodingBuffer buffer(estimatedSize, 0);
84 wireEncode(buffer);
85
86 m_wire = buffer.block();
87 return m_wire;
88}
89
90void
92{
93 if (wire.type() != tlv::ValidityPeriod) {
94 NDN_THROW(Error("ValidityPeriod", wire.type()));
95 }
96 m_wire = wire;
97 m_wire.parse();
98
99 if (m_wire.elements_size() != 2) {
100 NDN_THROW(Error("ValidityPeriod does not have two sub-elements"));
101 }
102 if (m_wire.elements()[NOT_BEFORE_OFFSET].type() != tlv::NotBefore ||
103 m_wire.elements()[NOT_BEFORE_OFFSET].value_size() != ISO_DATETIME_SIZE) {
104 NDN_THROW(Error("Missing or invalid NotBefore field"));
105 }
106 if (m_wire.elements()[NOT_AFTER_OFFSET].type() != tlv::NotAfter ||
107 m_wire.elements()[NOT_AFTER_OFFSET].value_size() != ISO_DATETIME_SIZE) {
108 NDN_THROW(Error("Missing or invalid NotAfter field"));
109 }
110
111 try {
112 m_notBefore = decodeTimePoint(m_wire.elements()[NOT_BEFORE_OFFSET]);
113 m_notAfter = decodeTimePoint(m_wire.elements()[NOT_AFTER_OFFSET]);
114 }
115 catch (const std::bad_cast&) {
116 NDN_THROW(Error("Invalid date format in NotBefore or NotAfter field"));
117 }
118}
119
120ValidityPeriod::TimePoint
121ValidityPeriod::toTimePointFloor(const time::system_clock::time_point& t)
122{
123 return TimePoint(boost::chrono::floor<TimePoint::duration>(t.time_since_epoch()));
124}
125
126ValidityPeriod::TimePoint
127ValidityPeriod::toTimePointCeil(const time::system_clock::time_point& t)
128{
129 return TimePoint(boost::chrono::ceil<TimePoint::duration>(t.time_since_epoch()));
130}
131
132ValidityPeriod::TimePoint
133ValidityPeriod::decodeTimePoint(const Block& element)
134{
135 // Bug #5176, prevent time::system_clock::time_point under/overflow
136 static const auto minTime = toTimePointCeil(time::system_clock::time_point::min());
137 static const auto maxTime = toTimePointFloor(time::system_clock::time_point::max());
138 static const auto minValue = time::toIsoString(minTime);
139 static const auto maxValue = time::toIsoString(maxTime);
140 BOOST_ASSERT(minValue.size() == ISO_DATETIME_SIZE);
141 BOOST_ASSERT(maxValue.size() == ISO_DATETIME_SIZE);
142
143 auto value = readString(element);
144 BOOST_ASSERT(value.size() == ISO_DATETIME_SIZE);
145
146 if (value < minValue) {
147 return minTime;
148 }
149 if (value > maxValue) {
150 return maxTime;
151 }
152 return time_point_cast<TimePoint::duration>(time::fromIsoString(value));
153}
154
157 const time::system_clock::time_point& notAfter)
158{
159 m_wire.reset();
160 m_notBefore = toTimePointCeil(notBefore);
161 m_notAfter = toTimePointFloor(notAfter);
162 return *this;
163}
164
165std::pair<time::system_clock::time_point, time::system_clock::time_point>
167{
168 return {m_notBefore, m_notAfter};
169}
170
171bool
173{
174 return m_notBefore <= now && now <= m_notAfter;
175}
176
177std::ostream&
178operator<<(std::ostream& os, const ValidityPeriod& period)
179{
180 os << "(" << time::toIsoString(period.getPeriod().first)
181 << ", " << time::toIsoString(period.getPeriod().second) << ")";
182 return os;
183}
184
185} // namespace ndn::security
Represents a TLV element of the NDN packet format.
Definition block.hpp:45
const element_container & elements() const noexcept
Get container of sub-elements.
Definition block.hpp:424
size_t elements_size() const noexcept
Equivalent to elements().size().
Definition block.hpp:451
bool hasWire() const noexcept
Check if the Block contains a fully encoded wire representation.
Definition block.hpp:205
uint32_t type() const noexcept
Return the TLV-TYPE of the Block.
Definition block.hpp:275
void reset() noexcept
Reset the Block to a default-constructed state.
Definition block.cpp:293
void parse() const
Parse TLV-VALUE into sub-elements.
Definition block.cpp:326
Represents a ValidityPeriod TLV element.
ValidityPeriod()
Create a validity period that is invalid for any timepoint.
static ValidityPeriod makeRelative(time::seconds validFrom, time::seconds validUntil, const time::system_clock::time_point &now=time::system_clock::now())
Construct ValidityPeriod relative to a timepoint.
std::pair< time::system_clock::time_point, time::system_clock::time_point > getPeriod() const
Get the stored validity period.
bool isValid(const time::system_clock::time_point &now=time::system_clock::now()) const
Check if now falls within the validity period.
void wireDecode(const Block &wire)
Decode ValidityPeriod from TLV block.
ValidityPeriod & setPeriod(const time::system_clock::time_point &notBefore, const time::system_clock::time_point &notAfter)
Set validity period [notBefore, notAfter].
const Block & wireEncode() const
Encode ValidityPeriod into TLV block.
::boost::chrono::time_point< system_clock > time_point
Definition time.hpp:205
#define NDN_CXX_DEFINE_WIRE_ENCODE_INSTANTIATIONS(ClassName)
#define NDN_THROW(e)
Definition exception.hpp:56
Contains the ndn-cxx security framework.
std::ostream & operator<<(std::ostream &os, const AdditionalDescription &desc)
constexpr size_t NOT_AFTER_OFFSET
constexpr size_t ISO_DATETIME_SIZE
constexpr size_t NOT_BEFORE_OFFSET
::boost::chrono::seconds seconds
Definition time.hpp:51
std::string toIsoString(const system_clock::time_point &timePoint)
Convert to the ISO 8601 string representation, basic format (YYYYMMDDTHHMMSS,fffffffff).
Definition time.cpp:130
system_clock::time_point fromIsoString(const std::string &isoString)
Convert from the ISO 8601 basic string format (YYYYMMDDTHHMMSS,fffffffff) to the internal time format...
Definition time.cpp:155
@ ValidityPeriod
Definition tlv.hpp:107
@ NotAfter
Definition tlv.hpp:109
@ NotBefore
Definition tlv.hpp:108