31 #ifndef _SCC_CRYPTO_DER_H
32 #define _SCC_CRYPTO_DER_H
44 namespace scc::crypto {
84 std::vector<uint8_t> m_data;
91 uint32_t
width()
const {
return m_width; }
96 return m_width%8 == 0 ? 0 : 8 - m_width%8;
103 m_data.resize(((v+7)&~7)/8,
'\x00');
104 for (uint32_t i = 0; i <
pad_bits(); i++)
106 m_data.at(m_data.size()-1) &= ~(1 << i);
114 void set(
const std::vector<uint8_t>& v,
size_t w)
119 void set(
const std::vector<char>& v,
size_t w)
122 m_data.insert(m_data.begin(), v.begin(), v.end());
129 if (bit >= m_width)
return false;
131 uint8_t mask = 1 << (7-bit%8);
133 return (m_data.at(bit/8) & mask) == mask ?
true :
false;
139 if (bit >= m_width)
return;
141 uint8_t mask = 1 << (7-bit%8);
143 if (
set) m_data.at(bit/8) |= mask;
144 else m_data.at(bit/8) &= ~mask;
154 void get(std::vector<uint8_t>& v)
const
158 void get(std::vector<char>& v)
const
161 v.insert(v.begin(), m_data.begin(), m_data.end());
166 using BasePtr = std::shared_ptr<DerBase>;
168 using oid_value = std::vector<uint32_t>;
179 std::vector<uint8_t> m_dat;
190 construct_mask = 0x20,
192 class_application = 0x40,
193 class_context = 0x80,
194 class_private = 0xc0,
195 length_multi_mask = 0x80,
196 length_bytes_mask = 0x7f,
200 type_octet_string = 4,
202 type_object_identifier = 6,
203 type_utf8_string = 12,
206 type_printable_string = 19,
207 type_teletex_string = 20,
208 type_ia5_string = 22,
210 type_generalized_time = 24,
211 type_visible_string = 26,
212 type_universal_string = 28,
213 type_bmp_string = 30,
220 DerBase(uint8_t tag = 0) : m_eloff(0), m_elsz(0), m_hdrsz(0), m_tag(tag), m_id(0) {}
223 explicit_bzero(m_dat.data(), m_dat.size());
227 static BasePtr
create(
int);
229 static BasePtr
create(
const std::vector<uint8_t>&,
size_t);
274 size_t eloff()
const {
return m_eloff; }
275 void eloff(
size_t v) { m_eloff = v; }
277 size_t elsz()
const {
return m_elsz; }
278 void elsz(
size_t v) { m_elsz = v; }
280 size_t hdrsz()
const {
return m_hdrsz; }
281 void hdrsz(
size_t v) { m_hdrsz = v; }
286 virtual size_t len()
const {
return m_dat.size(); }
289 virtual void parse(
const std::vector<uint8_t>& v) { m_dat = v; }
292 virtual void dump_pre(std::vector<char>&)
const;
294 virtual void dump_data(std::vector<char>&)
const;
297 virtual std::string
str(uint32_t=100)
const;
299 virtual std::string
data_str()
const;
301 virtual std::string name()
const {
return "DerBase"; }
304 std::vector<uint8_t>&
data() {
return m_dat; }
316 void set_base(
const std::vector<char>& v)
318 m_dat.assign(v.begin(), v.end());
327 return (m_tag & id_mask) == id_mask ? m_id : m_tag & id_mask;
333 m_tag = (m_tag & ~id_mask) | v;
344 std::string
id_str()
const;
349 void type_class(uint8_t f) { m_tag = (m_tag & ~class_mask) | (f & class_mask); }
352 bool uni_class()
const {
return (m_tag & class_mask) == 0; }
354 bool app_class()
const {
return (m_tag & class_mask) == class_application; }
356 bool context_class()
const {
return (m_tag & class_mask) == class_context; }
358 bool priv_class()
const {
return (m_tag & class_mask) == class_private; }
364 bool constructed()
const {
return m_tag & construct_mask ? true :
false; }
366 void constructed(
bool cons) { m_tag = cons ? m_tag | construct_mask : m_tag & ~construct_mask; }
382 std::vector<BasePtr>&
contain();
420 void string(
const std::string&);
454 return std::chrono::system_clock::from_time_t(
time_epoch());
472 virtual std::string
data_str()
const;
473 virtual void parse(
const std::vector<uint8_t>& v) { }
475 virtual size_t len()
const;
476 virtual std::string name()
const = 0;
491 virtual std::string name()
const {
return "DerSequence"; }
506 virtual std::string name()
const {
return "DerSet"; }
515 virtual void parse(
const std::vector<uint8_t>&) {}
517 virtual std::string
data_str()
const {
return ""; }
518 virtual void dump_data(std::vector<char>& v)
const { v.resize(0); }
519 virtual size_t len()
const {
return 0; }
520 virtual std::string name()
const {
return "DerNull"; }
530 explicit_bzero(&m_bool,
sizeof(
bool));
533 virtual void parse(
const std::vector<uint8_t>&);
535 virtual std::string
data_str()
const {
return m_bool ?
" true" :
" false"; }
536 virtual void dump_data(std::vector<char>& v)
const;
537 virtual size_t len()
const {
return 1; }
538 virtual std::string name()
const {
return "DerBoolean"; }
540 bool get()
const {
return m_bool; }
541 void set(
bool b) { m_bool = b; }
556 oid_value m_v = {0,0};
562 explicit_bzero(m_v.data(), m_v.size());
565 virtual void parse(
const std::vector<uint8_t>&);
567 virtual std::string
data_str()
const;
568 virtual size_t len()
const;
569 virtual void dump_data(std::vector<char>& v)
const;
570 virtual std::string name()
const {
return "DerObjectIdentifier"; }
579 void set(
const oid_value& v);
581 void get(oid_value& v)
const
586 std::string oid_str()
const;
603 explicit_bzero(&m_t,
sizeof(time_t));
607 time_t
epoch()
const {
return m_t; }
612 void set_time(
int year,
int month,
int day,
int hour,
int minute,
int second);
614 void set_time(
int year,
int month,
int day,
int hour,
int minute,
int second,
int tzmins);
616 virtual std::string name()
const = 0;
617 virtual std::string
data_str()
const;
631 virtual void parse(
const std::vector<uint8_t>&);
633 virtual void dump_data(std::vector<char>& v)
const;
634 virtual size_t len()
const;
635 virtual std::string name()
const {
return "DerUtcTime"; }
650 virtual void parse(
const std::vector<uint8_t>&);
652 virtual void dump_data(std::vector<char>& v)
const;
653 virtual size_t len()
const;
654 virtual std::string name()
const {
return "DerGeneralizedTime"; }
662 std::vector<uint8_t> m_val;
668 explicit_bzero(m_val.data(), m_val.size());
671 virtual void parse(
const std::vector<uint8_t>&);
673 virtual std::string
data_str()
const;
674 virtual void dump_data(std::vector<char>& v)
const;
675 virtual size_t len()
const {
return m_val.size(); }
676 virtual std::string name()
const = 0;
680 return std::string(m_val.begin(), m_val.end());
683 void get(std::vector<uint8_t>& v)
688 void get(std::vector<char>& v)
691 v.insert(v.begin(), m_val.begin(), m_val.end());
694 void get(std::string& v)
697 v.insert(v.begin(), m_val.begin(), m_val.end());
700 void set(
const std::vector<uint8_t>& v)
705 void set(
const std::vector<char>& v)
708 m_val.insert(m_val.begin(), v.begin(), v.end());
711 void set(
const std::string& v)
714 m_val.insert(m_val.begin(), v.begin(), v.end());
723 virtual std::string name()
const {
return "DerTeletexString"; }
731 virtual std::string name()
const {
return "DerVisibleString"; }
739 virtual std::string name()
const {
return "DerUniversalString"; }
747 virtual std::string name()
const {
return "DerOctetString"; }
755 virtual std::string name()
const {
return "DerUtf8String"; }
763 virtual std::string name()
const {
return "DerPrintableString"; }
771 virtual std::string name()
const {
return "DerIa5String"; }
779 virtual std::string name()
const {
return "DerBmpString"; }
789 virtual void parse(
const std::vector<uint8_t>&);
791 virtual std::string
data_str()
const;
792 virtual size_t len()
const;
793 virtual void dump_data(std::vector<char>&)
const;
794 virtual std::string name()
const {
return "DerInteger"; }
809 virtual void parse(
const std::vector<uint8_t>&);
811 virtual std::string
data_str()
const;
812 virtual size_t len()
const;
813 virtual void dump_data(std::vector<char>& v)
const;
814 virtual std::string name()
const {
return "DerBitString"; }
840 m_root.reset(b.m_root.get());
845 m_root.reset(b.m_root.get());
858 v.insert(v.end(), m_bin.begin(), m_bin.end());
870 static BasePtr
parse_element(
const std::vector<uint8_t>&,
size_t = 0);
872 static BasePtr
parse_element(
const std::vector<char>& v,
size_t idx = 0)
874 std::vector<uint8_t> b(v.begin(), v.end());
882 static void dump_element(
const BasePtr&, std::vector<uint8_t>&);
883 static void dump_element(
const BasePtr& b, std::vector<char>& v)
887 v.insert(v.end(), d.begin(), d.end());
898 static std::string
print_element(
const BasePtr&,
bool =
false,
const std::string& =
" |");
904 virtual void parse(
const std::vector<char>&);
908 virtual void parse(std::istream&);
914 virtual void dump(std::vector<char>&);
918 virtual void dump(std::ostream&);
926 std::string
str(
bool =
false)
const;
952 unsigned m_chars_per_line;
956 PemDocument(
const std::string& label,
unsigned chars_per_line = 64) :
DerDocument(), m_chars_per_line(chars_per_line), m_label(label) {}
959 unsigned chars_per_line()
const {
return m_chars_per_line; }
960 void chars_per_line(
unsigned v) { m_chars_per_line = v; }
961 std::string label()
const {
return m_label; }
962 void label(std::string v) { m_label = v; }
972 virtual void parse(std::istream&);
976 virtual void parse(
const std::vector<char>&);
986 virtual void dump(std::vector<char>&);
992 virtual void dump(std::ostream&);
1005 std::ostream&
operator<<(std::ostream&,
const std::vector<uint32_t>&);
bool is_bit_set(uint32_t bit) const
Is the bit set? First bit is bit 0.
uint32_t pad_bits() const
Number of padding bits (0 bits at the end of the last byte).
void get(std::vector< uint8_t > &v) const
Resize and get the vector.
void clear_bit(uint32_t bit)
Clear a bit.
void width(uint32_t v)
Set width in bits.
uint32_t width() const
Bit width.
void set(const std::vector< uint8_t > &v, size_t w)
Set the bit string from a bit string input.
void set_bit(uint32_t bit, bool set=true)
Set a bit.
scc::crypto::Bignum & integer()
Return reference to a scc::crypto::Bignum.
bool app_class() const
Application class.
bool is_utf8_string() const
Is this a utf8 (ascii) string?
BitString & bit_string()
Return reference to bit string.
bool is_teletex_string() const
Is this a teletex (ascii) string?
virtual void dump_pre(std::vector< char > &) const
Dump prefix data.
void get_base(std::vector< uint8_t > &v) const
Get raw data.
void set_base(const std::vector< uint8_t > &v)
Set raw data.
time_t time_epoch()
Epoch time.
virtual std::string data_str() const
Print vizualized data.
static BasePtr explicit_to_context(const BasePtr &BasePtr, uint32_t)
Convert explicit to context.
static BasePtr implicit_to_context(const BasePtr &BasePtr, uint32_t)
Convert implicit to context.
bool is_bit_string() const
Is this a DerBitString?
bool is_universal_string() const
Is this a univeral (ascii) string?
bool context_class() const
Context class.
size_t elsz() const
Binary vector element length, not including the header.
bool is_visible_string() const
Is this a visible (ascii) string?
virtual void parse(const std::vector< uint8_t > &v)
Parse raw data into the object.
DerBase(uint8_t tag=0)
Construct a base object.
oid_value object_id()
Return the object identifier value.
bool priv_class() const
Private class.
std::chrono::system_clock::time_point time_point()
Time point.
static BasePtr context_to_explicit(const BasePtr &)
Change a context element to explicit.
bool is_boolean() const
Is this a boolean type?
bool is_utc_time() const
Is this a utc time type?
bool is_contain() const
Is this a container type?
bool boolean()
Return boolean value.
bool is_octet_string() const
Is this an octet string (8 bit chars)?
void constructed(bool cons)
Set constructed flag.
static BasePtr create(int)
Create a base pointer, using only the tag byte.
size_t pre_len() const
The length of prefix bytes (tag/id, and length).
bool is_seq() const
Is this a sequence type?
bool is_string() const
Is this a generic ascii string?
bool is_time() const
Is this a time type?
bool uni_class() const
Universal class.
std::vector< uint8_t > & data()
Underlying data.
std::string string()
Return string.
void string_set(const std::vector< char > &)
Set string vector.
void type_class(uint8_t f)
Set type class.
std::vector< BasePtr > & contain()
Return container, or throw an error if this is not a container.
bool constructed() const
Constructed flag (bit 6).
std::string class_str() const
String version of the classification.
bool is_ia5_string() const
Is this an ia5 (ascii) string?
virtual void dump_data(std::vector< char > &) const
Dump data.
uint8_t type_class() const
Classification of the type (bits 7-8)
static BasePtr context_to_implicit(const BasePtr &, uint32_t)
Change a context element to implicit.
bool is_bmp_string() const
Is this a bmp (ascii) string?
bool is_null() const
Is this a null type?
bool is_printable_string() const
Is this a printable string?
bool is_set() const
Is this a set type?
void string_get(std::vector< char > &)
Get string vector.
size_t hdrsz() const
Header size of the element (tag, id, and length bytes).
size_t eloff() const
Offset of the element into the binary vector.
bool is_integer() const
Is this a DerInteger?
bool is_object_id() const
Is this an object identifier?
std::string construct_str() const
String version of the construct flag.
virtual std::string str(uint32_t=100) const
Print summary line to maximum width.
std::string id_str() const
String version of the id.
virtual size_t len() const
Length of the data.
bool is_generalized_time() const
Is this as generalized time type?
uint32_t id() const
Tag id of the type.
virtual void parse(const std::vector< uint8_t > &)
Parse raw data into the object.
virtual std::string data_str() const
Print vizualized data.
virtual size_t len() const
Length of the data.
virtual void dump_data(std::vector< char > &v) const
Dump data.
virtual std::string data_str() const
Print vizualized data.
virtual void dump_data(std::vector< char > &v) const
Dump data.
virtual size_t len() const
Length of the data.
virtual void parse(const std::vector< uint8_t > &)
Parse raw data into the object.
virtual size_t len() const
Length of the data.
virtual void parse(const std::vector< uint8_t > &v)
Parse raw data into the object.
virtual void dump_data(std::vector< char > &v) const
Dump data.
virtual std::string data_str() const
Print vizualized data.
void clear()
Clear the document.
void dump_bin(std::vector< char > &v) const
Dump the binary vector.
bool equal(const DerDocument &) const
Compare binary data.
std::string str(bool=false) const
Debug string dump.
virtual void dump(std::vector< char > &)
Dump and append to a buffer.
static std::string print_element(const BasePtr &, bool=false, const std::string &=" |")
Print an element and any sub-elements to a string.
BasePtr root_ptr() const
Return the root pointer.
static void dump_element(const BasePtr &, std::vector< uint8_t > &)
Dump an element to a data vector.
virtual void parse(const std::vector< char > &)
Parse a buffer from a binary DER-formatted vector.
DerBase & root()
Root DerBase.
static BasePtr parse_element(const std::vector< uint8_t > &, size_t=0)
Parse an element from a data vector.
virtual void dump_data(std::vector< char > &v) const
Dump data.
virtual void parse(const std::vector< uint8_t > &)
Parse raw data into the object.
virtual size_t len() const
Length of the data.
virtual std::string data_str() const
Print vizualized data.
virtual void dump_data(std::vector< char > &) const
Dump data.
virtual size_t len() const
Length of the data.
scc::crypto::Bignum & data()
Return the integer (an scc::crypto::Bignum)
virtual void parse(const std::vector< uint8_t > &)
Parse raw data into the object.
virtual void parse(const std::vector< uint8_t > &)
Parse raw data into the object.
virtual void dump_data(std::vector< char > &v) const
Dump data.
virtual std::string data_str() const
Print vizualized data.
virtual size_t len() const
Length of the data.
virtual void dump_data(std::vector< char > &v) const
Dump data.
virtual void parse(const std::vector< uint8_t > &)
Parse raw data into the object.
void set(const oid_value &v)
Set oid values.
virtual std::string data_str() const
Print vizualized data.
virtual size_t len() const
Length of the data.
An ASN.1 SEQUENCE or SEQUENCE OF type.
An ASN.1 SET or SET OF type.
All strings derive from simple string base class.
virtual void dump_data(std::vector< char > &v) const
Dump data.
virtual void parse(const std::vector< uint8_t > &)
Parse raw data into the object.
virtual size_t len() const
Length of the data.
virtual std::string data_str() const
Print vizualized data.
void epoch(time_t v)
Set epoch time.
virtual std::string data_str() const
Print vizualized data.
time_t epoch() const
Epoch time (seconds since Jan 1, 1970), in the local time zone.
void set_time(int year, int month, int day, int hour, int minute, int second)
Set time in the local time zone.
virtual void parse(const std::vector< uint8_t > &)
Parse raw data into the object.
virtual void dump_data(std::vector< char > &v) const
Dump data.
virtual size_t len() const
Length of the data.
PEM formatted DER document.
virtual void parse(std::istream &)
Parse document from an input stream.
virtual void dump(std::vector< char > &)
PEM-formatted dump to a buffer.
std::ostream & operator<<(std::ostream &, const scc::crypto::DerBase &)
Print out base and all sub-elements.