Coverage Report

Created: 2020-05-23 13:54

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