Botan 3.13.0
Crypto and TLS for C&
Botan::ASN1_Time Class Referencefinal

#include <asn1_time.h>

Inheritance diagram for Botan::ASN1_Time:
Botan::ASN1_Object

Public Member Functions

 ASN1_Time ()=default
 Create an invalid ASN1_Time.
 ASN1_Time (const std::chrono::system_clock::time_point &time)
 Create a ASN1_Time from a time point.
BOTAN_FUTURE_EXPLICIT ASN1_Time (std::string_view t_spec)
 Create an ASN1_Time from string.
 ASN1_Time (std::string_view t_spec, ASN1_Type tag)
 Create an ASN1_Time from string and a specified tagging (Utc or Generalized).
std::vector< uint8_t > BER_encode () const
int32_t cmp (const ASN1_Time &other) const
 Compare this time against another.
void decode_from (BER_Decoder &from) override
void encode_into (DER_Encoder &to) const override
 DER encode a ASN1_Time.
std::string readable_string () const
 Returns a human friendly string representation of no particular formatting.
ASN1_Type tagging () const
 Return the tag (UtcTime or GeneralizedTime) this time was encoded with.
bool time_is_set () const
 Return if the time has been set somehow.
uint64_t time_since_epoch () const
 Return time since epoch.
std::chrono::system_clock::time_point to_std_timepoint () const
 Returns a STL timepoint object.
std::string to_string () const
 Return an internal string representation of the time.

Static Public Member Functions

static ASN1_Time from_seconds_since_epoch (uint64_t seconds)
 Create an ASN1_Time from seconds since epoch.
static ASN1_Time from_string (std::string_view t_spec)
static ASN1_Time from_string (std::string_view t_spec, ASN1_Type tag)
static ASN1_Time from_time_point (const std::chrono::system_clock::time_point &time)
 Create a ASN1_Time from a time point.

Detailed Description

Time (GeneralizedTime/UniversalTime)

Definition at line 18 of file asn1_time.h.

Constructor & Destructor Documentation

◆ ASN1_Time() [1/4]

Botan::ASN1_Time::ASN1_Time ( )
default

◆ ASN1_Time() [2/4]

Botan::ASN1_Time::ASN1_Time ( const std::chrono::system_clock::time_point & time)
inlineexplicit

Create a ASN1_Time from a time point.

Definition at line 64 of file asn1_time.h.

64 {
65 *this = ASN1_Time::from_time_point(time);
66 }
static ASN1_Time from_time_point(const std::chrono::system_clock::time_point &time)
Create a ASN1_Time from a time point.
Definition asn1_time.cpp:94

References from_time_point().

◆ ASN1_Time() [3/4]

BOTAN_FUTURE_EXPLICIT Botan::ASN1_Time::ASN1_Time ( std::string_view t_spec)
inline

Create an ASN1_Time from string.

Definition at line 69 of file asn1_time.h.

69{ *this = ASN1_Time::from_string(t_spec); }
static ASN1_Time from_string(std::string_view t_spec)

References BOTAN_FUTURE_EXPLICIT, and from_string().

◆ ASN1_Time() [4/4]

Botan::ASN1_Time::ASN1_Time ( std::string_view t_spec,
ASN1_Type tag )
inline

Create an ASN1_Time from string and a specified tagging (Utc or Generalized).

Definition at line 72 of file asn1_time.h.

72{ *this = ASN1_Time::from_string(t_spec, tag); }

References from_string().

Member Function Documentation

◆ BER_encode()

std::vector< uint8_t > Botan::ASN1_Object::BER_encode ( ) const
inherited

Return the encoding of this object. This is a convenience method when just one object needs to be serialized. Use DER_Encoder for complicated encodings.

Definition at line 21 of file asn1_obj.cpp.

21 {
22 std::vector<uint8_t> output;
23 DER_Encoder der(output);
24 this->encode_into(der);
25 return output;
26}
virtual void encode_into(DER_Encoder &to) const =0

References encode_into().

Referenced by decode_from(), Botan::PKCS12::export_to(), Botan::Certificate_Store_In_SQL::find_all_certs(), Botan::Certificate_Store_In_SQL::find_cert(), Botan::X509_Certificate::fingerprint(), Botan::Certificate_Store_In_SQL::insert_cert(), Botan::X509_Object::PEM_encode(), and Botan::PSS_Params::PSS_Params().

◆ cmp()

int32_t Botan::ASN1_Time::cmp ( const ASN1_Time & other) const

Compare this time against another.

Definition at line 237 of file asn1_time.cpp.

237 {
238 if(!time_is_set() || !other.time_is_set()) {
239 throw Invalid_State("ASN1_Time::cmp: Cannot compare empty times");
240 }
241
242 constexpr int32_t EARLIER = -1;
243 constexpr int32_t LATER = 1;
244 constexpr int32_t SAME_TIME = 0;
245
246 if(m_year < other.m_year) {
247 return EARLIER;
248 }
249 if(m_year > other.m_year) {
250 return LATER;
251 }
252 if(m_month < other.m_month) {
253 return EARLIER;
254 }
255 if(m_month > other.m_month) {
256 return LATER;
257 }
258 if(m_day < other.m_day) {
259 return EARLIER;
260 }
261 if(m_day > other.m_day) {
262 return LATER;
263 }
264 if(m_hour < other.m_hour) {
265 return EARLIER;
266 }
267 if(m_hour > other.m_hour) {
268 return LATER;
269 }
270 if(m_minute < other.m_minute) {
271 return EARLIER;
272 }
273 if(m_minute > other.m_minute) {
274 return LATER;
275 }
276 if(m_second < other.m_second) {
277 return EARLIER;
278 }
279 if(m_second > other.m_second) {
280 return LATER;
281 }
282
283 return SAME_TIME;
284}
bool time_is_set() const
Return if the time has been set somehow.

References ASN1_Time(), and time_is_set().

Referenced by Botan::operator!=(), Botan::operator<(), Botan::operator<=(), Botan::operator==(), Botan::operator>(), and Botan::operator>=().

◆ decode_from()

void Botan::ASN1_Time::decode_from ( BER_Decoder & from)
overridevirtual

Decode whatever this object is from from

Parameters
fromthe BER_Decoder that will be read from

Implements Botan::ASN1_Object.

Definition at line 168 of file asn1_time.cpp.

168 {
169 const BER_Object ber_time = source.get_next_object();
170
171 if(ber_time.get_class() != ASN1_Class::Universal ||
172 (ber_time.type() != ASN1_Type::UtcTime && ber_time.type() != ASN1_Type::GeneralizedTime)) {
173 throw Decoding_Error(fmt("ASN1_Time: Unexpected tag {}/{}",
174 static_cast<uint32_t>(ber_time.type()),
175 static_cast<uint32_t>(ber_time.get_class())));
176 }
177
178 try {
179 // Assigning only after a successful parse means that a decoding error
180 // cannot leave this object in a partially written state
181 *this = ASN1_Time::from_string(ASN1::to_string(ber_time), ber_time.type());
182 } catch(Invalid_Argument& e) {
183 throw Decoding_Error(fmt("Invalid ASN1_Time encoding: {}", e.what()));
184 }
185}
std::string to_string(const BER_Object &obj)
Definition asn1_obj.cpp:224
std::string fmt(std::string_view format, const T &... args)
Definition fmt.h:53

References Botan::fmt(), from_string(), Botan::GeneralizedTime, Botan::BER_Object::get_class(), Botan::BER_Decoder::get_next_object(), Botan::ASN1::to_string(), Botan::BER_Object::type(), Botan::Universal, Botan::UtcTime, and Botan::Exception::what().

◆ encode_into()

void Botan::ASN1_Time::encode_into ( DER_Encoder & to) const
overridevirtual

DER encode a ASN1_Time.

Implements Botan::ASN1_Object.

Definition at line 162 of file asn1_time.cpp.

162 {
163 BOTAN_ARG_CHECK(m_tag == ASN1_Type::UtcTime || m_tag == ASN1_Type::GeneralizedTime, "ASN1_Time: Bad encoding tag");
164
165 der.add_object(m_tag, ASN1_Class::Universal, to_string());
166}
#define BOTAN_ARG_CHECK(expr, msg)
Definition assert.h:33
std::string to_string() const
Return an internal string representation of the time.

References Botan::DER_Encoder::add_object(), BOTAN_ARG_CHECK, Botan::GeneralizedTime, to_string(), Botan::Universal, and Botan::UtcTime.

◆ from_seconds_since_epoch()

ASN1_Time Botan::ASN1_Time::from_seconds_since_epoch ( uint64_t seconds)
static

Create an ASN1_Time from seconds since epoch.

Definition at line 37 of file asn1_time.cpp.

37 {
38 return ASN1_Time::from_time_point(std::chrono::system_clock::time_point(std::chrono::seconds(time_since_epoch)));
39}
uint64_t time_since_epoch() const
Return time since epoch.

References ASN1_Time(), from_time_point(), and time_since_epoch().

Referenced by ASN1_Time().

◆ from_string() [1/2]

ASN1_Time Botan::ASN1_Time::from_string ( std::string_view t_spec)
static

Create a ASN1_Time from a string

Only the fixed 13 or 15 char RFC 5280 format (eg [YY]YYMMDDHHMMSSZ) is accepted, tag is set based on the use of 2 or 4 digit year, 2-digit years use the 1950 breakeven point (see RFC 5280 Section 4.1.2.5.1)

Definition at line 152 of file asn1_time.cpp.

152 {
153 if(t_spec.size() == 13) {
155 } else if(t_spec.size() == 15) {
157 } else {
158 throw Invalid_Argument("Time string could not be parsed as GeneralizedTime or UTCTime.");
159 }
160}

References ASN1_Time(), from_string(), Botan::GeneralizedTime, and Botan::UtcTime.

Referenced by ASN1_Time(), ASN1_Time(), ASN1_Time(), decode_from(), and from_string().

◆ from_string() [2/2]

ASN1_Time Botan::ASN1_Time::from_string ( std::string_view t_spec,
ASN1_Type tag )
static

Create a ASN1_Time from a string

Only the fixed 13 or 15 char RFC 5280 format (eg [YY]YYMMDDHHMMSSZ) is accepted, based on the provided tag (which must be UtcTime or GeneralizedTime)

Definition at line 109 of file asn1_time.cpp.

109 {
110 BOTAN_ARG_CHECK(tag == ASN1_Type::UtcTime || tag == ASN1_Type::GeneralizedTime, "Invalid tag for ASN1_Time");
111
112 if(tag == ASN1_Type::GeneralizedTime) {
113 BOTAN_ARG_CHECK(t_spec.size() == 15, "Invalid GeneralizedTime input string");
114 } else {
115 BOTAN_ARG_CHECK(t_spec.size() == 13, "Invalid UTCTime input string");
116 }
117
118 BOTAN_ARG_CHECK(t_spec.back() == 'Z', "Botan does not support ASN1 times with timezones other than Z");
119
120 const size_t field_len = 2;
121 const size_t year_len = (tag == ASN1_Type::UtcTime) ? 2 : 4;
122
123 const size_t year_start = 0;
124 const size_t month_start = year_start + year_len;
125 const size_t day_start = month_start + field_len;
126 const size_t hour_start = day_start + field_len;
127 const size_t min_start = hour_start + field_len;
128 const size_t sec_start = min_start + field_len;
129
130 uint32_t year = to_u32bit(t_spec.substr(year_start, year_len));
131 const uint32_t month = to_u32bit(t_spec.substr(month_start, field_len));
132 const uint32_t day = to_u32bit(t_spec.substr(day_start, field_len));
133 const uint32_t hour = to_u32bit(t_spec.substr(hour_start, field_len));
134 const uint32_t minute = to_u32bit(t_spec.substr(min_start, field_len));
135 const uint32_t second = to_u32bit(t_spec.substr(sec_start, field_len));
136
137 if(tag == ASN1_Type::UtcTime) {
138 // Interpret the two digit year by the 1950/2050 split (RFC 5280 Section 4.1.2.5.1)
139 year += (year >= 50) ? 1900 : 2000;
140 }
141
142 return ASN1_Time(static_cast<uint16_t>(year),
143 static_cast<uint8_t>(month),
144 static_cast<uint8_t>(day),
145 static_cast<uint8_t>(hour),
146 static_cast<uint8_t>(minute),
147 static_cast<uint8_t>(second),
148 tag);
149}
ASN1_Time()=default
Create an invalid ASN1_Time.
uint32_t to_u32bit(std::string_view input)
Definition parsing.cpp:76

References ASN1_Time(), BOTAN_ARG_CHECK, Botan::GeneralizedTime, Botan::to_u32bit(), and Botan::UtcTime.

◆ from_time_point()

ASN1_Time Botan::ASN1_Time::from_time_point ( const std::chrono::system_clock::time_point & time)
static

Create a ASN1_Time from a time point.

Definition at line 94 of file asn1_time.cpp.

94 {
95 const calendar_point cal(time);
96
97 const ASN1_Type tag = (cal.year() >= 2050) ? ASN1_Type::GeneralizedTime : ASN1_Type::UtcTime;
98
99 return ASN1_Time(static_cast<uint16_t>(cal.year()),
100 static_cast<uint8_t>(cal.month()),
101 static_cast<uint8_t>(cal.day()),
102 static_cast<uint8_t>(cal.hour()),
103 static_cast<uint8_t>(cal.minutes()),
104 static_cast<uint8_t>(cal.seconds()),
105 tag);
106}
ASN1_Type
Definition asn1_obj.h:47

References ASN1_Time(), Botan::calendar_point::day(), Botan::GeneralizedTime, Botan::calendar_point::hour(), Botan::calendar_point::minutes(), Botan::calendar_point::month(), Botan::calendar_point::seconds(), Botan::UtcTime, and Botan::calendar_point::year().

Referenced by ASN1_Time(), ASN1_Time(), and from_seconds_since_epoch().

◆ readable_string()

std::string Botan::ASN1_Time::readable_string ( ) const

Returns a human friendly string representation of no particular formatting.

Definition at line 218 of file asn1_time.cpp.

218 {
219 if(!time_is_set()) {
220 throw Invalid_State("ASN1_Time::readable_string: No time set");
221 }
222
223 // desired format: "YYYY/MM/DD HH:MM:SS UTC"
224
225 std::ostringstream out;
226
227 out << zero_pad(m_year, 4) << "/" << zero_pad(m_month, 2) << "/" << zero_pad(m_day, 2) << " ";
228 out << zero_pad(m_hour, 2) << ":" << zero_pad(m_minute, 2) << ":" << zero_pad(m_second, 2) << " UTC";
229
230 return out.str();
231}

References time_is_set().

Referenced by to_string(), and Botan::X509_Certificate::to_string().

◆ tagging()

ASN1_Type Botan::ASN1_Time::tagging ( ) const
inline

Return the tag (UtcTime or GeneralizedTime) this time was encoded with.

Definition at line 36 of file asn1_time.h.

36{ return m_tag; }

◆ time_is_set()

bool Botan::ASN1_Time::time_is_set ( ) const

Return if the time has been set somehow.

Definition at line 233 of file asn1_time.cpp.

233 {
234 return (m_year != 0);
235}

Referenced by cmp(), readable_string(), Botan::Certificate_Store_In_SQL::revoke_cert(), and to_string().

◆ time_since_epoch()

uint64_t Botan::ASN1_Time::time_since_epoch ( ) const

Return time since epoch.

Definition at line 290 of file asn1_time.cpp.

290 {
291 const int64_t tse = calendar_point(m_year, m_month, m_day, m_hour, m_minute, m_second).seconds_since_epoch();
292
293 if(tse >= 0) {
294 return static_cast<uint64_t>(tse);
295 } else {
296 throw Encoding_Error("ASN1_Time::time_since_epoch value is prior to epoch");
297 }
298}

References Botan::calendar_point::seconds_since_epoch().

Referenced by botan_x509_crl_entry_revocation_date(), and from_seconds_since_epoch().

◆ to_std_timepoint()

std::chrono::system_clock::time_point Botan::ASN1_Time::to_std_timepoint ( ) const

Returns a STL timepoint object.

Definition at line 286 of file asn1_time.cpp.

286 {
287 return calendar_point(m_year, m_month, m_day, m_hour, m_minute, m_second).to_std_timepoint();
288}

References Botan::calendar_point::to_std_timepoint().

Referenced by Botan::Certificate_Store_In_SQL::revoke_cert().

◆ to_string()

std::string Botan::ASN1_Time::to_string ( ) const

Return an internal string representation of the time.

Definition at line 187 of file asn1_time.cpp.

187 {
188 if(!time_is_set()) {
189 throw Invalid_State("ASN1_Time::to_string: No time set");
190 }
191
192 BOTAN_ASSERT_NOMSG(m_year <= 9999);
193
194 std::ostringstream out;
195
196 // UTCTime uses a 2 digit year, GeneralizedTime a 4 digit year
197 if(m_tag == ASN1_Type::UtcTime) {
198 if(m_year < 1950 || m_year >= 2050) {
199 throw Encoding_Error(fmt("ASN_Time: The time {} cannot be encoded as UTCTime", readable_string()));
200 }
201
202 out << (zero_pad((m_year >= 2000) ? (m_year - 2000) : (m_year - 1900), 2));
203 } else {
204 out << zero_pad(m_year, 4);
205 }
206
207 // clang-format off
208 out << zero_pad(m_month, 2)
209 << zero_pad(m_day, 2)
210 << zero_pad(m_hour, 2)
211 << zero_pad(m_minute, 2)
212 << zero_pad(m_second, 2) << "Z";
213 // clang-format on
214
215 return out.str();
216}
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:75
std::string readable_string() const
Returns a human friendly string representation of no particular formatting.

References BOTAN_ASSERT_NOMSG, Botan::fmt(), readable_string(), time_is_set(), and Botan::UtcTime.

Referenced by encode_into().


The documentation for this class was generated from the following files: