Botan  2.6.0
Crypto and TLS for C++11
asn1_obj.cpp
Go to the documentation of this file.
1 /*
2 * ASN.1 Internals
3 * (C) 1999-2007 Jack Lloyd
4 *
5 * Botan is released under the Simplified BSD License (see license.txt)
6 */
7 
8 #include <botan/asn1_obj.h>
9 #include <botan/der_enc.h>
10 #include <botan/data_src.h>
11 #include <botan/internal/stl_util.h>
12 
13 namespace Botan {
14 
15 /*
16 * Check a type invariant on BER data
17 */
18 void BER_Object::assert_is_a(ASN1_Tag type_tag_, ASN1_Tag class_tag_,
19  const std::string& descr) const
20  {
21  if(this->is_a(type_tag_, class_tag_) == false)
22  {
23  throw BER_Decoding_Error("Tag mismatch when decoding " + descr + " got " +
24  std::to_string(type_tag) + "/" +
25  std::to_string(class_tag) + " expected " +
26  std::to_string(type_tag_) + "/" +
27  std::to_string(class_tag_));
28  }
29  }
30 
31 bool BER_Object::is_a(ASN1_Tag type_tag_, ASN1_Tag class_tag_) const
32  {
33  return (type_tag == type_tag_ && class_tag == class_tag_);
34  }
35 
36 bool BER_Object::is_a(int type_tag_, ASN1_Tag class_tag_) const
37  {
38  return is_a(ASN1_Tag(type_tag_), class_tag_);
39  }
40 
41 void BER_Object::set_tagging(ASN1_Tag t, ASN1_Tag c)
42  {
43  type_tag = t;
44  class_tag = c;
45  }
46 
48  {
49  switch(type)
50  {
51  case Botan::SEQUENCE:
52  return "SEQUENCE";
53 
54  case Botan::SET:
55  return "SET";
56 
58  return "PRINTABLE STRING";
59 
61  return "NUMERIC STRING";
62 
63  case Botan::IA5_STRING:
64  return "IA5 STRING";
65 
66  case Botan::T61_STRING:
67  return "T61 STRING";
68 
69  case Botan::UTF8_STRING:
70  return "UTF8 STRING";
71 
73  return "VISIBLE STRING";
74 
75  case Botan::BMP_STRING:
76  return "BMP STRING";
77 
78  case Botan::UTC_TIME:
79  return "UTC TIME";
80 
82  return "GENERALIZED TIME";
83 
85  return "OCTET STRING";
86 
87  case Botan::BIT_STRING:
88  return "BIT STRING";
89 
90  case Botan::ENUMERATED:
91  return "ENUMERATED";
92 
93  case Botan::INTEGER:
94  return "INTEGER";
95 
96  case Botan::NULL_TAG:
97  return "NULL";
98 
99  case Botan::OBJECT_ID:
100  return "OBJECT";
101 
102  case Botan::BOOLEAN:
103  return "BOOLEAN";
104 
105  default:
106  return "TAG(" + std::to_string(static_cast<size_t>(type)) + ")";
107  }
108  }
109 
110 /*
111 * BER Decoding Exceptions
112 */
113 BER_Decoding_Error::BER_Decoding_Error(const std::string& str) :
114  Decoding_Error("BER: " + str) {}
115 
116 BER_Bad_Tag::BER_Bad_Tag(const std::string& str, ASN1_Tag tag) :
117  BER_Decoding_Error(str + ": " + std::to_string(tag)) {}
118 
119 BER_Bad_Tag::BER_Bad_Tag(const std::string& str,
120  ASN1_Tag tag1, ASN1_Tag tag2) :
121  BER_Decoding_Error(str + ": " + std::to_string(tag1) + "/" + std::to_string(tag2)) {}
122 
123 namespace ASN1 {
124 
125 /*
126 * Put some arbitrary bytes into a SEQUENCE
127 */
128 std::vector<uint8_t> put_in_sequence(const std::vector<uint8_t>& contents)
129  {
130  return ASN1::put_in_sequence(contents.data(), contents.size());
131  }
132 
133 std::vector<uint8_t> put_in_sequence(const uint8_t bits[], size_t len)
134  {
135  return DER_Encoder()
137  .raw_bytes(bits, len)
138  .end_cons()
140  }
141 
142 /*
143 * Convert a BER object into a string object
144 */
145 std::string to_string(const BER_Object& obj)
146  {
147  return std::string(cast_uint8_ptr_to_char(obj.bits()),
148  obj.length());
149  }
150 
151 /*
152 * Do heuristic tests for BER data
153 */
154 bool maybe_BER(DataSource& source)
155  {
156  uint8_t first_u8;
157  if(!source.peek_byte(first_u8))
158  {
159  BOTAN_ASSERT_EQUAL(source.read_byte(first_u8), 0, "Expected EOF");
160  throw Stream_IO_Error("ASN1::maybe_BER: Source was empty");
161  }
162 
163  if(first_u8 == (SEQUENCE | CONSTRUCTED))
164  return true;
165  return false;
166  }
167 
168 }
169 
170 }
std::vector< uint8_t > get_contents_unlocked()
Definition: der_enc.h:27
bool is_a(ASN1_Tag type_tag, ASN1_Tag class_tag) const
Definition: asn1_obj.cpp:31
void assert_is_a(ASN1_Tag type_tag, ASN1_Tag class_tag, const std::string &descr="object") const
Definition: asn1_obj.cpp:18
std::string asn1_tag_to_string(ASN1_Tag type)
Definition: asn1_obj.cpp:47
Definition: bigint.h:719
bool maybe_BER(DataSource &source)
Definition: asn1_obj.cpp:154
std::string to_string(const BER_Object &obj)
Definition: asn1_obj.cpp:145
ASN1_Tag
Definition: asn1_obj.h:22
MechanismType type
DER_Encoder & end_cons()
Definition: der_enc.cpp:146
DER_Encoder & raw_bytes(const uint8_t val[], size_t len)
Definition: der_enc.cpp:181
BOTAN_DEPRECATED_PUBLIC_MEMBER_VARIABLES class_tag
Definition: asn1_obj.h:117
#define BOTAN_ASSERT_EQUAL(expr1, expr2, assertion_made)
Definition: assert.h:56
BER_Bad_Tag(const std::string &msg, ASN1_Tag tag)
Definition: asn1_obj.cpp:116
size_t length() const
Definition: asn1_obj.h:102
Definition: alg_id.cpp:13
size_t read_byte(uint8_t &out)
Definition: data_src.cpp:23
std::vector< uint8_t > put_in_sequence(const std::vector< uint8_t > &contents)
Definition: asn1_obj.cpp:128
const uint8_t * bits() const
Definition: asn1_obj.h:100
std::string to_string(const secure_vector< uint8_t > &bytes)
Definition: stl_util.h:25
size_t peek_byte(uint8_t &out) const
Definition: data_src.cpp:31
const char * cast_uint8_ptr_to_char(const uint8_t *b)
Definition: mem_ops.h:136
DER_Encoder & start_cons(ASN1_Tag type_tag, ASN1_Tag class_tag=UNIVERSAL)
Definition: der_enc.cpp:136
BER_Decoding_Error(const std::string &)
Definition: asn1_obj.cpp:113