• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

randombit / botan / 5141471000

01 Jun 2023 07:52AM UTC coverage: 91.753% (+0.01%) from 91.742%
5141471000

Pull #3549

github

web-flow
Merge d8b50706e into 44282e9fe
Pull Request #3549: SPHINCS+

77102 of 84032 relevant lines covered (91.75%)

12125455.15 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

93.64
/src/lib/asn1/asn1_obj.cpp
1
/*
2
* ASN.1 Internals
3
* (C) 1999-2007,2018 Jack Lloyd
4
*
5
* Botan is released under the Simplified BSD License (see license.txt)
6
*/
7

8
#include <botan/asn1_obj.h>
9

10
#include <botan/data_src.h>
11
#include <botan/der_enc.h>
12
#include <botan/internal/fmt.h>
13
#include <botan/internal/stl_util.h>
14
#include <sstream>
15

16
namespace Botan {
17

18
std::vector<uint8_t> ASN1_Object::BER_encode() const {
19,361✔
19
   std::vector<uint8_t> output;
19,361✔
20
   DER_Encoder der(output);
19,361✔
21
   this->encode_into(der);
19,361✔
22
   return output;
19,361✔
23
}
19,361✔
24

25
/*
26
* Check a type invariant on BER data
27
*/
28
void BER_Object::assert_is_a(ASN1_Type expected_type_tag, ASN1_Class expected_class_tag, std::string_view descr) const {
835,627✔
29
   if(this->is_a(expected_type_tag, expected_class_tag) == false) {
835,627✔
30
      std::stringstream msg;
3,303✔
31

32
      msg << "Tag mismatch when decoding " << descr << " got ";
3,303✔
33

34
      if(m_class_tag == ASN1_Class::NoObject && m_type_tag == ASN1_Type::NoObject) {
3,303✔
35
         msg << "EOF";
1,099✔
36
      } else {
37
         if(m_class_tag == ASN1_Class::Universal || m_class_tag == ASN1_Class::Constructed) {
2,204✔
38
            msg << asn1_tag_to_string(m_type_tag);
3,468✔
39
         } else {
40
            msg << std::to_string(static_cast<uint32_t>(m_type_tag));
948✔
41
         }
42

43
         msg << "/" << asn1_class_to_string(m_class_tag);
4,504✔
44
      }
45

46
      msg << " expected ";
3,303✔
47

48
      if(expected_class_tag == ASN1_Class::Universal || expected_class_tag == ASN1_Class::Constructed) {
3,303✔
49
         msg << asn1_tag_to_string(expected_type_tag);
6,508✔
50
      } else {
51
         msg << std::to_string(static_cast<uint32_t>(expected_type_tag));
98✔
52
      }
53

54
      msg << "/" << asn1_class_to_string(expected_class_tag);
6,606✔
55

56
      throw BER_Decoding_Error(msg.str());
6,606✔
57
   }
3,303✔
58
}
832,324✔
59

60
bool BER_Object::is_a(ASN1_Type expected_type_tag, ASN1_Class expected_class_tag) const {
1,083,103✔
61
   return (m_type_tag == expected_type_tag && m_class_tag == expected_class_tag);
1,083,103✔
62
}
63

64
bool BER_Object::is_a(int expected_type_tag, ASN1_Class expected_class_tag) const {
109,955✔
65
   return is_a(ASN1_Type(expected_type_tag), expected_class_tag);
109,955✔
66
}
67

68
void BER_Object::set_tagging(ASN1_Type type_tag, ASN1_Class class_tag) {
6,400,103✔
69
   m_type_tag = type_tag;
6,400,103✔
70
   m_class_tag = class_tag;
6,400,103✔
71
}
6,400,103✔
72

73
std::string asn1_class_to_string(ASN1_Class type) {
5,507✔
74
   switch(type) {
5,507✔
75
      case ASN1_Class::Universal:
2,503✔
76
         return "UNIVERSAL";
2,503✔
77
      case ASN1_Class::Constructed:
2,481✔
78
         return "CONSTRUCTED";
2,481✔
79
      case ASN1_Class::ContextSpecific:
96✔
80
         return "CONTEXT_SPECIFIC";
96✔
81
      case ASN1_Class::Application:
45✔
82
         return "APPLICATION";
45✔
83
      case ASN1_Class::Private:
40✔
84
         return "PRIVATE";
40✔
85
      case ASN1_Class::NoObject:
×
86
         return "NO_OBJECT";
×
87
      default:
342✔
88
         return "CLASS(" + std::to_string(static_cast<size_t>(type)) + ")";
684✔
89
   }
90
}
91

92
std::string asn1_tag_to_string(ASN1_Type type) {
5,405✔
93
   switch(type) {
5,405✔
94
      case ASN1_Type::Sequence:
2,130✔
95
         return "SEQUENCE";
2,130✔
96

97
      case ASN1_Type::Set:
236✔
98
         return "SET";
236✔
99

100
      case ASN1_Type::PrintableString:
20✔
101
         return "PRINTABLE STRING";
20✔
102

103
      case ASN1_Type::NumericString:
22✔
104
         return "NUMERIC STRING";
22✔
105

106
      case ASN1_Type::Ia5String:
10✔
107
         return "IA5 STRING";
10✔
108

109
      case ASN1_Type::TeletexString:
7✔
110
         return "T61 STRING";
7✔
111

112
      case ASN1_Type::Utf8String:
61✔
113
         return "UTF8 STRING";
61✔
114

115
      case ASN1_Type::VisibleString:
6✔
116
         return "VISIBLE STRING";
6✔
117

118
      case ASN1_Type::BmpString:
4✔
119
         return "BMP STRING";
4✔
120

121
      case ASN1_Type::UniversalString:
×
122
         return "UNIVERSAL STRING";
×
123

124
      case ASN1_Type::UtcTime:
143✔
125
         return "UTC TIME";
143✔
126

127
      case ASN1_Type::GeneralizedTime:
8✔
128
         return "GENERALIZED TIME";
8✔
129

130
      case ASN1_Type::OctetString:
293✔
131
         return "OCTET STRING";
293✔
132

133
      case ASN1_Type::BitString:
172✔
134
         return "BIT STRING";
172✔
135

136
      case ASN1_Type::Enumerated:
48✔
137
         return "ENUMERATED";
48✔
138

139
      case ASN1_Type::Integer:
1,520✔
140
         return "INTEGER";
1,520✔
141

142
      case ASN1_Type::Null:
116✔
143
         return "NULL";
116✔
144

145
      case ASN1_Type::ObjectId:
97✔
146
         return "OBJECT";
97✔
147

148
      case ASN1_Type::Boolean:
78✔
149
         return "BOOLEAN";
78✔
150

151
      case ASN1_Type::NoObject:
×
152
         return "NO_OBJECT";
×
153

154
      default:
434✔
155
         return "TAG(" + std::to_string(static_cast<uint32_t>(type)) + ")";
868✔
156
   }
157
}
158

159
/*
160
* BER Decoding Exceptions
161
*/
162
BER_Decoding_Error::BER_Decoding_Error(std::string_view str) : Decoding_Error(fmt("BER: {}", str)) {}
29,316✔
163

164
BER_Bad_Tag::BER_Bad_Tag(std::string_view str, uint32_t tagging) : BER_Decoding_Error(fmt("{}: {}", str, tagging)) {}
3,652✔
165

166
namespace ASN1 {
167

168
/*
169
* Put some arbitrary bytes into a SEQUENCE
170
*/
171
std::vector<uint8_t> put_in_sequence(const std::vector<uint8_t>& contents) {
55,182✔
172
   return ASN1::put_in_sequence(contents.data(), contents.size());
55,182✔
173
}
174

175
std::vector<uint8_t> put_in_sequence(const uint8_t bits[], size_t len) {
55,344✔
176
   std::vector<uint8_t> output;
55,344✔
177
   DER_Encoder(output).start_sequence().raw_bytes(bits, len).end_cons();
110,688✔
178
   return output;
55,344✔
179
}
×
180

181
/*
182
* Convert a BER object into a string object
183
*/
184
std::string to_string(const BER_Object& obj) { return std::string(cast_uint8_ptr_to_char(obj.bits()), obj.length()); }
156,880✔
185

186
/*
187
* Do heuristic tests for BER data
188
*/
189
bool maybe_BER(DataSource& source) {
41,865✔
190
   uint8_t first_u8;
41,865✔
191
   if(!source.peek_byte(first_u8)) {
41,865✔
192
      BOTAN_ASSERT_EQUAL(source.read_byte(first_u8), 0, "Expected EOF");
205✔
193
      throw Stream_IO_Error("ASN1::maybe_BER: Source was empty");
205✔
194
   }
195

196
   const auto cons_seq = static_cast<uint8_t>(ASN1_Class::Constructed) | static_cast<uint8_t>(ASN1_Type::Sequence);
41,660✔
197
   if(first_u8 == cons_seq) {
41,660✔
198
      return true;
35,055✔
199
   }
200
   return false;
201
}
202

203
}  // namespace ASN1
204

205
}  // namespace Botan
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc