Coverage Report

Created: 2020-06-30 13:58

/src/botan/src/lib/asn1/asn1_str.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
* Simple ASN.1 String Types
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_str.h>
9
#include <botan/der_enc.h>
10
#include <botan/ber_dec.h>
11
#include <botan/charset.h>
12
13
namespace Botan {
14
15
namespace {
16
17
/*
18
* Choose an encoding for the string
19
*/
20
ASN1_Tag choose_encoding(const std::string& str)
21
116k
   {
22
116k
   static const uint8_t IS_PRINTABLE[256] = {
23
116k
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
24
116k
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
25
116k
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
26
116k
      0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,
27
116k
      0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00,
28
116k
      0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
29
116k
      0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
30
116k
      0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
31
116k
      0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
32
116k
      0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
33
116k
      0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
34
116k
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
35
116k
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
36
116k
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
37
116k
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
38
116k
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
39
116k
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
40
116k
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
41
116k
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
42
116k
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
43
116k
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
44
116k
      0x00, 0x00, 0x00, 0x00 };
45
116k
46
116k
   for(size_t i = 0; i != str.size(); ++i)
47
0
      {
48
0
      if(!IS_PRINTABLE[static_cast<uint8_t>(str[i])])
49
0
         {
50
0
         return UTF8_STRING;
51
0
         }
52
0
      }
53
116k
   return PRINTABLE_STRING;
54
116k
   }
55
56
void assert_is_string_type(ASN1_Tag tag)
57
117k
   {
58
117k
   if(!ASN1_String::is_string_type(tag))
59
456
      {
60
456
      throw Invalid_Argument("ASN1_String: Unknown string type " +
61
456
                             std::to_string(tag));
62
456
      }
63
117k
   }
64
65
}
66
67
//static
68
bool ASN1_String::is_string_type(ASN1_Tag tag)
69
161k
   {
70
161k
   return (tag == NUMERIC_STRING ||
71
161k
           tag == PRINTABLE_STRING ||
72
161k
           tag == VISIBLE_STRING ||
73
161k
           tag == T61_STRING ||
74
161k
           tag == IA5_STRING ||
75
161k
           tag == UTF8_STRING ||
76
161k
           tag == BMP_STRING ||
77
161k
           tag == UNIVERSAL_STRING);
78
161k
   }
79
80
81
/*
82
* Create an ASN1_String
83
*/
84
ASN1_String::ASN1_String(const std::string& str, ASN1_Tag t) : m_utf8_str(str), m_tag(t)
85
2.18k
   {
86
2.18k
   if(m_tag == DIRECTORY_STRING)
87
0
      {
88
0
      m_tag = choose_encoding(m_utf8_str);
89
0
      }
90
2.18k
91
2.18k
   assert_is_string_type(m_tag);
92
2.18k
   }
93
94
/*
95
* Create an ASN1_String
96
*/
97
ASN1_String::ASN1_String(const std::string& str) :
98
   m_utf8_str(str),
99
   m_tag(choose_encoding(m_utf8_str))
100
116k
   {}
101
102
/*
103
* Return this string in ISO 8859-1 encoding
104
*/
105
std::string ASN1_String::iso_8859() const
106
0
   {
107
0
   return utf8_to_latin1(m_utf8_str);
108
0
   }
109
110
/*
111
* DER encode an ASN1_String
112
*/
113
void ASN1_String::encode_into(DER_Encoder& encoder) const
114
864
   {
115
864
   if(m_data.empty())
116
864
      {
117
864
      encoder.add_object(tagging(), UNIVERSAL, m_utf8_str);
118
864
      }
119
0
   else
120
0
      {
121
0
      // If this string was decoded, reserialize using original encoding
122
0
      encoder.add_object(tagging(), UNIVERSAL, m_data.data(), m_data.size());
123
0
      }
124
864
   }
125
126
/*
127
* Decode a BER encoded ASN1_String
128
*/
129
void ASN1_String::decode_from(BER_Decoder& source)
130
115k
   {
131
115k
   BER_Object obj = source.get_next_object();
132
115k
133
115k
   assert_is_string_type(obj.type());
134
115k
135
115k
   m_tag = obj.type();
136
115k
   m_data.assign(obj.bits(), obj.bits() + obj.length());
137
115k
138
115k
   if(m_tag == BMP_STRING)
139
4.04k
      {
140
4.04k
      m_utf8_str = ucs2_to_utf8(m_data.data(), m_data.size());
141
4.04k
      }
142
111k
   else if(m_tag == UNIVERSAL_STRING)
143
3.06k
      {
144
3.06k
      m_utf8_str = ucs4_to_utf8(m_data.data(), m_data.size());
145
3.06k
      }
146
108k
   else
147
108k
      {
148
108k
      // All other supported string types are UTF-8 or some subset thereof
149
108k
      m_utf8_str = ASN1::to_string(obj);
150
108k
      }
151
115k
   }
152
153
}