Botan  1.10.9
asn1_str.cpp
Go to the documentation of this file.
1 /*
2 * Simple ASN.1 String Types
3 * (C) 1999-2007 Jack Lloyd
4 *
5 * Distributed under the terms of the Botan license
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 #include <botan/parsing.h>
13 
14 namespace Botan {
15 
16 namespace {
17 
18 /*
19 * Choose an encoding for the string
20 */
21 ASN1_Tag choose_encoding(const std::string& str,
22  const std::string& type)
23  {
24  static const byte IS_PRINTABLE[256] = {
25  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
26  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
27  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
28  0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,
29  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00,
30  0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
31  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
32  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
33  0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
34  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
35  0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
36  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
37  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
38  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
39  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
40  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
41  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
42  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
43  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
44  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
45  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
46  0x00, 0x00, 0x00, 0x00 };
47 
48  for(size_t i = 0; i != str.size(); ++i)
49  {
50  if(!IS_PRINTABLE[static_cast<byte>(str[i])])
51  {
52  if(type == "utf8") return UTF8_STRING;
53  if(type == "latin1") return T61_STRING;
54  throw Invalid_Argument("choose_encoding: Bad string type " + type);
55  }
56  }
57  return PRINTABLE_STRING;
58  }
59 
60 }
61 
62 /*
63 * Create an ASN1_String
64 */
65 ASN1_String::ASN1_String(const std::string& str, ASN1_Tag t) : tag(t)
66  {
67  iso_8859_str = Charset::transcode(str, LOCAL_CHARSET, LATIN1_CHARSET);
68 
69  if(tag == DIRECTORY_STRING)
70  tag = choose_encoding(iso_8859_str, "latin1");
71 
72  if(tag != NUMERIC_STRING &&
73  tag != PRINTABLE_STRING &&
74  tag != VISIBLE_STRING &&
75  tag != T61_STRING &&
76  tag != IA5_STRING &&
77  tag != UTF8_STRING &&
78  tag != BMP_STRING)
79  throw Invalid_Argument("ASN1_String: Unknown string type " +
80  to_string(tag));
81  }
82 
83 /*
84 * Create an ASN1_String
85 */
86 ASN1_String::ASN1_String(const std::string& str)
87  {
88  iso_8859_str = Charset::transcode(str, LOCAL_CHARSET, LATIN1_CHARSET);
89  tag = choose_encoding(iso_8859_str, "latin1");
90  }
91 
92 /*
93 * Return this string in ISO 8859-1 encoding
94 */
95 std::string ASN1_String::iso_8859() const
96  {
97  return iso_8859_str;
98  }
99 
100 /*
101 * Return this string in local encoding
102 */
103 std::string ASN1_String::value() const
104  {
105  return Charset::transcode(iso_8859_str, LATIN1_CHARSET, LOCAL_CHARSET);
106  }
107 
108 /*
109 * Return the type of this string object
110 */
112  {
113  return tag;
114  }
115 
116 /*
117 * DER encode an ASN1_String
118 */
120  {
121  std::string value = iso_8859();
122  if(tagging() == UTF8_STRING)
124  encoder.add_object(tagging(), UNIVERSAL, value);
125  }
126 
127 /*
128 * Decode a BER encoded ASN1_String
129 */
131  {
132  BER_Object obj = source.get_next_object();
133 
134  Character_Set charset_is;
135 
136  if(obj.type_tag == BMP_STRING)
137  charset_is = UCS2_CHARSET;
138  else if(obj.type_tag == UTF8_STRING)
139  charset_is = UTF8_CHARSET;
140  else
141  charset_is = LATIN1_CHARSET;
142 
143  *this = ASN1_String(
145  obj.type_tag);
146  }
147 
148 }
ASN1_Tag tagging() const
Definition: asn1_str.cpp:111
std::string value() const
Definition: asn1_str.cpp:103
std::invalid_argument Invalid_Argument
Definition: exceptn.h:20
std::string to_string(const BER_Object &obj)
Definition: asn1_int.cpp:46
Character_Set
Definition: charset.h:19
unsigned char byte
Definition: types.h:22
std::string transcode(const std::string &str, Character_Set to, Character_Set from)
Definition: charset.cpp:103
ASN1_String(const std::string &="")
Definition: asn1_str.cpp:86
ASN1_Tag
Definition: asn1_int.h:19
void decode_from(class BER_Decoder &)
Definition: asn1_str.cpp:130
BER_Object get_next_object()
Definition: ber_dec.cpp:193
std::string iso_8859() const
Definition: asn1_str.cpp:95
ASN1_Tag type_tag
Definition: asn1_int.h:82
std::string to_string(u64bit n, size_t min_len)
Definition: parsing.cpp:42
void encode_into(class DER_Encoder &) const
Definition: asn1_str.cpp:119
DER_Encoder & add_object(ASN1_Tag type_tag, ASN1_Tag class_tag, const byte rep[], size_t length)
Definition: der_enc.cpp:346