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

randombit / botan / 4892192195

05 May 2023 10:32AM UTC coverage: 91.732% (+0.008%) from 91.724%
4892192195

push

github

77631 of 84628 relevant lines covered (91.73%)

11913034.27 hits per line

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

94.02
/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/der_enc.h>
11
#include <botan/data_src.h>
12
#include <botan/internal/stl_util.h>
13
#include <botan/internal/fmt.h>
14
#include <sstream>
15

16
namespace Botan {
17

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

26
/*
27
* Check a type invariant on BER data
28
*/
29
void BER_Object::assert_is_a(ASN1_Type expected_type_tag, ASN1_Class expected_class_tag,
822,923✔
30
                             std::string_view descr) const
31
   {
32
   if(this->is_a(expected_type_tag, expected_class_tag) == false)
822,923✔
33
      {
34
      std::stringstream msg;
3,307✔
35

36
      msg << "Tag mismatch when decoding " << descr << " got ";
3,307✔
37

38
      if(m_class_tag == ASN1_Class::NoObject && m_type_tag == ASN1_Type::NoObject)
3,307✔
39
         {
40
         msg << "EOF";
1,100✔
41
         }
42
      else
43
         {
44
         if(m_class_tag == ASN1_Class::Universal || m_class_tag == ASN1_Class::Constructed)
2,207✔
45
            {
46
            msg << asn1_tag_to_string(m_type_tag);
3,470✔
47
            }
48
         else
49
            {
50
            msg << std::to_string(static_cast<uint32_t>(m_type_tag));
952✔
51
            }
52

53
         msg << "/" << asn1_class_to_string(m_class_tag);
4,509✔
54
         }
55

56
      msg << " expected ";
3,307✔
57

58
      if(expected_class_tag == ASN1_Class::Universal || expected_class_tag == ASN1_Class::Constructed)
3,307✔
59
         {
60
         msg << asn1_tag_to_string(expected_type_tag);
6,516✔
61
         }
62
      else
63
         {
64
         msg << std::to_string(static_cast<uint32_t>(expected_type_tag));
98✔
65
         }
66

67
      msg << "/" << asn1_class_to_string(expected_class_tag);
6,614✔
68

69
      throw BER_Decoding_Error(msg.str());
6,614✔
70
      }
3,307✔
71
   }
819,616✔
72

73
bool BER_Object::is_a(ASN1_Type expected_type_tag, ASN1_Class expected_class_tag) const
1,067,675✔
74
   {
75
   return (m_type_tag == expected_type_tag && m_class_tag == expected_class_tag);
1,067,675✔
76
   }
77

78
bool BER_Object::is_a(int expected_type_tag, ASN1_Class expected_class_tag) const
109,516✔
79
   {
80
   return is_a(ASN1_Type(expected_type_tag), expected_class_tag);
109,516✔
81
   }
82

83
void BER_Object::set_tagging(ASN1_Type type_tag, ASN1_Class class_tag)
6,380,223✔
84
   {
85
   m_type_tag = type_tag;
6,380,223✔
86
   m_class_tag = class_tag;
6,380,223✔
87
   }
6,380,223✔
88

89
std::string asn1_class_to_string(ASN1_Class type)
5,514✔
90
   {
91
   switch(type)
5,514✔
92
      {
93
      case ASN1_Class::Universal:
2,506✔
94
         return "UNIVERSAL";
2,506✔
95
      case ASN1_Class::Constructed:
2,483✔
96
         return "CONSTRUCTED";
2,483✔
97
      case ASN1_Class::ContextSpecific:
95✔
98
         return "CONTEXT_SPECIFIC";
95✔
99
      case ASN1_Class::Application:
44✔
100
         return "APPLICATION";
44✔
101
      case ASN1_Class::Private:
40✔
102
         return "PRIVATE";
40✔
103
      case ASN1_Class::NoObject:
×
104
         return "NO_OBJECT";
×
105
      default:
346✔
106
         return "CLASS(" + std::to_string(static_cast<size_t>(type)) + ")";
692✔
107
      }
108
   }
109

110
std::string asn1_tag_to_string(ASN1_Type type)
5,410✔
111
   {
112
   switch(type)
5,410✔
113
      {
114
      case ASN1_Type::Sequence:
2,132✔
115
         return "SEQUENCE";
2,132✔
116

117
      case ASN1_Type::Set:
236✔
118
         return "SET";
236✔
119

120
      case ASN1_Type::PrintableString:
20✔
121
         return "PRINTABLE STRING";
20✔
122

123
      case ASN1_Type::NumericString:
22✔
124
         return "NUMERIC STRING";
22✔
125

126
      case ASN1_Type::Ia5String:
10✔
127
         return "IA5 STRING";
10✔
128

129
      case ASN1_Type::TeletexString:
7✔
130
         return "T61 STRING";
7✔
131

132
      case ASN1_Type::Utf8String:
62✔
133
         return "UTF8 STRING";
62✔
134

135
      case ASN1_Type::VisibleString:
6✔
136
         return "VISIBLE STRING";
6✔
137

138
      case ASN1_Type::BmpString:
4✔
139
         return "BMP STRING";
4✔
140

141
      case ASN1_Type::UniversalString:
×
142
         return "UNIVERSAL STRING";
×
143

144
      case ASN1_Type::UtcTime:
143✔
145
         return "UTC TIME";
143✔
146

147
      case ASN1_Type::GeneralizedTime:
8✔
148
         return "GENERALIZED TIME";
8✔
149

150
      case ASN1_Type::OctetString:
295✔
151
         return "OCTET STRING";
295✔
152

153
      case ASN1_Type::BitString:
172✔
154
         return "BIT STRING";
172✔
155

156
      case ASN1_Type::Enumerated:
48✔
157
         return "ENUMERATED";
48✔
158

159
      case ASN1_Type::Integer:
1,520✔
160
         return "INTEGER";
1,520✔
161

162
      case ASN1_Type::Null:
117✔
163
         return "NULL";
117✔
164

165
      case ASN1_Type::ObjectId:
96✔
166
         return "OBJECT";
96✔
167

168
      case ASN1_Type::Boolean:
78✔
169
         return "BOOLEAN";
78✔
170

171
      case ASN1_Type::NoObject:
×
172
         return "NO_OBJECT";
×
173

174
      default:
434✔
175
         return "TAG(" + std::to_string(static_cast<uint32_t>(type)) + ")";
868✔
176
      }
177
   }
178

179
/*
180
* BER Decoding Exceptions
181
*/
182
BER_Decoding_Error::BER_Decoding_Error(std::string_view str) :
14,658✔
183
   Decoding_Error(fmt("BER: {}", str)) {}
29,316✔
184

185
BER_Bad_Tag::BER_Bad_Tag(std::string_view str, uint32_t tagging) :
1,826✔
186
   BER_Decoding_Error(fmt("{}: {}", str, tagging)) {}
3,652✔
187

188
namespace ASN1 {
189

190
/*
191
* Put some arbitrary bytes into a SEQUENCE
192
*/
193
std::vector<uint8_t> put_in_sequence(const std::vector<uint8_t>& contents)
54,255✔
194
   {
195
   return ASN1::put_in_sequence(contents.data(), contents.size());
54,255✔
196
   }
197

198
std::vector<uint8_t> put_in_sequence(const uint8_t bits[], size_t len)
54,417✔
199
   {
200
   std::vector<uint8_t> output;
54,417✔
201
   DER_Encoder(output)
108,834✔
202
      .start_sequence()
54,417✔
203
         .raw_bytes(bits, len)
54,417✔
204
      .end_cons();
54,417✔
205
   return output;
54,417✔
206
   }
×
207

208
/*
209
* Convert a BER object into a string object
210
*/
211
std::string to_string(const BER_Object& obj)
154,495✔
212
   {
213
   return std::string(cast_uint8_ptr_to_char(obj.bits()),
154,495✔
214
                      obj.length());
154,495✔
215
   }
216

217
/*
218
* Do heuristic tests for BER data
219
*/
220
bool maybe_BER(DataSource& source)
41,334✔
221
   {
222
   uint8_t first_u8;
41,334✔
223
   if(!source.peek_byte(first_u8))
41,334✔
224
      {
225
      BOTAN_ASSERT_EQUAL(source.read_byte(first_u8), 0, "Expected EOF");
205✔
226
      throw Stream_IO_Error("ASN1::maybe_BER: Source was empty");
205✔
227
      }
228

229
   const auto cons_seq = static_cast<uint8_t>(ASN1_Class::Constructed) | static_cast<uint8_t>(ASN1_Type::Sequence);
41,129✔
230
   if(first_u8 == cons_seq)
41,129✔
231
      return true;
34,564✔
232
   return false;
233
   }
234

235
}
236

237
}
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

© 2026 Coveralls, Inc