monotone

monotone Mtn Source Tree

Root/botan/asn1_str.cpp

1/*************************************************
2* Simple ASN.1 String Types Source File *
3* (C) 1999-2005 The Botan Project *
4*************************************************/
5
6#include <botan/asn1_obj.h>
7#include <botan/charset.h>
8#include <botan/parsing.h>
9#include <botan/conf.h>
10
11namespace Botan {
12
13namespace {
14
15/*************************************************
16* Choose an encoding for the string *
17*************************************************/
18ASN1_Tag choose_encoding(const std::string& str)
19 {
20 static const byte IS_PRINTABLE[256] = {
21 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
22 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
23 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
24 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,
25 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00,
26 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
27 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
28 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
29 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
30 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
31 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
32 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
33 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
34 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
35 0x00, 0x00, 0x00, 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 };
43
44 for(u32bit j = 0; j != str.size(); j++)
45 if(!IS_PRINTABLE[(byte)str[j]])
46 {
47 const std::string type = Config::get_string("x509/ca/str_type");
48 if(type == "utf8") return UTF8_STRING;
49 if(type == "latin1") return T61_STRING;
50 throw Invalid_Argument("Bad setting for x509/ca/str_type: " + type);
51 }
52 return PRINTABLE_STRING;
53 }
54
55}
56
57/*************************************************
58* Check if type is a known ASN.1 string type *
59*************************************************/
60bool is_string_type(ASN1_Tag tag)
61 {
62 if(tag == NUMERIC_STRING || tag == PRINTABLE_STRING ||
63 tag == VISIBLE_STRING || tag == T61_STRING || tag == IA5_STRING ||
64 tag == UTF8_STRING || tag == BMP_STRING)
65 return true;
66 return false;
67 }
68
69/*************************************************
70* Create an ASN1_String *
71*************************************************/
72ASN1_String::ASN1_String(const std::string& str, ASN1_Tag t) : tag(t)
73 {
74 iso_8859_str = local2iso(str);
75 if(tag == DIRECTORY_STRING)
76 tag = choose_encoding(iso_8859_str);
77
78 if(tag != NUMERIC_STRING &&
79 tag != PRINTABLE_STRING &&
80 tag != VISIBLE_STRING &&
81 tag != T61_STRING &&
82 tag != IA5_STRING &&
83 tag != UTF8_STRING &&
84 tag != BMP_STRING)
85 throw Invalid_Argument("ASN1_String: Unknown string type " +
86 to_string(tag));
87 }
88
89/*************************************************
90* Create an ASN1_String *
91*************************************************/
92ASN1_String::ASN1_String(const std::string& str)
93 {
94 iso_8859_str = local2iso(str);
95 tag = choose_encoding(iso_8859_str);
96 }
97
98/*************************************************
99* Return this string in ISO 8859-1 encoding *
100*************************************************/
101std::string ASN1_String::iso_8859() const
102 {
103 return iso_8859_str;
104 }
105
106/*************************************************
107* Return this string in local encoding *
108*************************************************/
109std::string ASN1_String::value() const
110 {
111 return iso2local(iso_8859_str);
112 }
113
114/*************************************************
115* Return the type of this string object *
116*************************************************/
117ASN1_Tag ASN1_String::tagging() const
118 {
119 return tag;
120 }
121
122namespace DER {
123
124/*************************************************
125* DER encode an ASN1_String *
126*************************************************/
127void encode(DER_Encoder& encoder, const ASN1_String& string,
128 ASN1_Tag type_tag, ASN1_Tag class_tag)
129 {
130 if(string.tagging() == UTF8_STRING)
131 encoder.add_object(type_tag, class_tag, iso2utf(string.iso_8859()));
132 else
133 encoder.add_object(type_tag, class_tag, string.iso_8859());
134 }
135
136/*************************************************
137* DER encode an ASN1_String *
138*************************************************/
139void encode(DER_Encoder& encoder, const ASN1_String& string)
140 {
141 DER::encode(encoder, string, string.tagging(), UNIVERSAL);
142 }
143
144}
145
146namespace BER {
147
148namespace {
149
150/*************************************************
151* Do any UTF-8/Unicode decoding needed *
152*************************************************/
153std::string convert_string(BER_Object obj, ASN1_Tag type)
154 {
155 if(type == BMP_STRING)
156 {
157 if(obj.value.size() % 2 == 1)
158 throw BER_Decoding_Error("BMP STRING has an odd number of bytes");
159
160 std::string value;
161 for(u32bit j = 0; j != obj.value.size(); j += 2)
162 {
163 const byte c1 = obj.value[j];
164 const byte c2 = obj.value[j+1];
165
166 if(c1 != 0)
167 throw BER_Decoding_Error("BMP STRING has non-Latin1 characters");
168
169 value += (char)c2;
170 }
171 return iso2local(value);
172 }
173 else if(type == UTF8_STRING)
174 return iso2local(utf2iso(BER::to_string(obj)));
175 else
176 return iso2local(BER::to_string(obj));
177 }
178
179}
180
181/*************************************************
182* Decode a BER encoded ASN1_String *
183*************************************************/
184void decode(BER_Decoder& source, ASN1_String& string,
185 ASN1_Tag expected_tag, ASN1_Tag real_tag)
186 {
187 BER_Object obj = source.get_next_object();
188 if(obj.type_tag != expected_tag)
189 throw BER_Bad_Tag("Unexpected string tag", obj.type_tag);
190
191 string = ASN1_String(convert_string(obj, real_tag), real_tag);
192 }
193
194/*************************************************
195* Decode a BER encoded ASN1_String *
196*************************************************/
197void decode(BER_Decoder& source, ASN1_String& string)
198 {
199 BER_Object obj = source.get_next_object();
200 string = ASN1_String(convert_string(obj, obj.type_tag), obj.type_tag);
201 }
202
203}
204
205}

Archive Download this file

Branches

Tags

Quick Links:     www.monotone.ca    -     Downloads    -     Documentation    -     Wiki    -     Code Forge    -     Build Status