Coverage Report

Created: 2020-10-17 06:46

/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
118k
   {
58
118k
   if(!ASN1_String::is_string_type(tag))
59
450
      {
60
450
      throw Invalid_Argument("ASN1_String: Unknown string type " +
61
450
                             std::to_string(tag));
62
450
      }
63
118k
   }
64
65
}
66
67
//static
68
bool ASN1_String::is_string_type(ASN1_Tag tag)
69
159k
   {
70
159k
   return (tag == NUMERIC_STRING ||
71
157k
           tag == PRINTABLE_STRING ||
72
125k
           tag == VISIBLE_STRING ||
73
110k
           tag == T61_STRING ||
74
107k
           tag == IA5_STRING ||
75
102k
           tag == UTF8_STRING ||
76
46.3k
           tag == BMP_STRING ||
77
41.4k
           tag == UNIVERSAL_STRING);
78
159k
   }
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.28k
   {
86
2.28k
   if(m_tag == DIRECTORY_STRING)
87
0
      {
88
0
      m_tag = choose_encoding(m_utf8_str);
89
0
      }
90
2.28k
91
2.28k
   assert_is_string_type(m_tag);
92
2.28k
   }
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
936
   {
115
936
   if(m_data.empty())
116
936
      {
117
936
      encoder.add_object(tagging(), UNIVERSAL, m_utf8_str);
118
936
      }
119
0
   else
120
0
      {
121
      // 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
936
   }
125
126
/*
127
* Decode a BER encoded ASN1_String
128
*/
129
void ASN1_String::decode_from(BER_Decoder& source)
130
116k
   {
131
116k
   BER_Object obj = source.get_next_object();
132
116k
133
116k
   assert_is_string_type(obj.type());
134
116k
135
116k
   m_tag = obj.type();
136
116k
   m_data.assign(obj.bits(), obj.bits() + obj.length());
137
116k
138
116k
   if(m_tag == BMP_STRING)
139
3.82k
      {
140
3.82k
      m_utf8_str = ucs2_to_utf8(m_data.data(), m_data.size());
141
3.82k
      }
142
112k
   else if(m_tag == UNIVERSAL_STRING)
143
3.27k
      {
144
3.27k
      m_utf8_str = ucs4_to_utf8(m_data.data(), m_data.size());
145
3.27k
      }
146
109k
   else
147
109k
      {
148
      // All other supported string types are UTF-8 or some subset thereof
149
109k
      m_utf8_str = ASN1::to_string(obj);
150
109k
      }
151
116k
   }
152
153
}