Coverage Report

Created: 2020-02-14 15:38

/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
114k
   {
22
114k
   static const uint8_t IS_PRINTABLE[256] = {
23
114k
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
24
114k
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
25
114k
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
26
114k
      0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,
27
114k
      0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00,
28
114k
      0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
29
114k
      0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
30
114k
      0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
31
114k
      0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
32
114k
      0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
33
114k
      0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
34
114k
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
35
114k
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
36
114k
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
37
114k
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
38
114k
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
39
114k
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
40
114k
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
41
114k
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
42
114k
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
43
114k
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
44
114k
      0x00, 0x00, 0x00, 0x00 };
45
114k
46
114k
   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
114k
   return PRINTABLE_STRING;
54
114k
   }
55
56
void assert_is_string_type(ASN1_Tag tag)
57
116k
   {
58
116k
   if(!ASN1_String::is_string_type(tag))
59
441
      {
60
441
      throw Invalid_Argument("ASN1_String: Unknown string type " +
61
441
                             std::to_string(tag));
62
441
      }
63
116k
   }
64
65
}
66
67
//static
68
bool ASN1_String::is_string_type(ASN1_Tag tag)
69
162k
   {
70
162k
   return (tag == NUMERIC_STRING ||
71
162k
           tag == PRINTABLE_STRING ||
72
162k
           tag == VISIBLE_STRING ||
73
162k
           tag == T61_STRING ||
74
162k
           tag == IA5_STRING ||
75
162k
           tag == UTF8_STRING ||
76
162k
           tag == BMP_STRING ||
77
162k
           tag == UNIVERSAL_STRING);
78
162k
   }
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.09k
   {
86
2.09k
   if(m_tag == DIRECTORY_STRING)
87
0
      {
88
0
      m_tag = choose_encoding(m_utf8_str);
89
0
      }
90
2.09k
91
2.09k
   assert_is_string_type(m_tag);
92
2.09k
   }
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
114k
   {}
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
738
   {
115
738
   if(m_data.empty())
116
738
      {
117
738
      encoder.add_object(tagging(), UNIVERSAL, m_utf8_str);
118
738
      }
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
738
   }
125
126
/*
127
* Decode a BER encoded ASN1_String
128
*/
129
void ASN1_String::decode_from(BER_Decoder& source)
130
114k
   {
131
114k
   BER_Object obj = source.get_next_object();
132
114k
133
114k
   assert_is_string_type(obj.type());
134
114k
135
114k
   m_tag = obj.type();
136
114k
   m_data.assign(obj.bits(), obj.bits() + obj.length());
137
114k
138
114k
   if(m_tag == BMP_STRING)
139
4.99k
      {
140
4.99k
      m_utf8_str = ucs2_to_utf8(m_data.data(), m_data.size());
141
4.99k
      }
142
109k
   else if(m_tag == UNIVERSAL_STRING)
143
2.28k
      {
144
2.28k
      m_utf8_str = ucs4_to_utf8(m_data.data(), m_data.size());
145
2.28k
      }
146
107k
   else
147
107k
      {
148
107k
      // All other supported string types are UTF-8 or some subset thereof
149
107k
      m_utf8_str = ASN1::to_string(obj);
150
107k
      }
151
114k
   }
152
153
}