1 /*
2 * Simple ASN.1 String Types
3 * (C) 2007 FlexSecure GmbH
4 * 2008-2011 Jack Lloyd
5 *
6 * Distributed under the terms of the Botan license
7 */
8
9 #include <botan/eac_asn_obj.h>
10 #include <botan/der_enc.h>
11 #include <botan/ber_dec.h>
12 #include <botan/charset.h>
13 #include <botan/parsing.h>
14 #include <sstream>
15 #include <ios>
16
17 namespace Botan {
18
19 /*
20 * Create an ASN1_EAC_String
21 */
ASN1_EAC_String(const std::string & str,ASN1_Tag t)22 ASN1_EAC_String::ASN1_EAC_String(const std::string& str, ASN1_Tag t) : tag(t)
23 {
24 iso_8859_str = Charset::transcode(str, LOCAL_CHARSET, LATIN1_CHARSET);
25
26 if(!sanity_check())
27 throw Invalid_Argument("ASN1_EAC_String contains illegal characters");
28 }
29
30 /*
31 * Return this string in ISO 8859-1 encoding
32 */
iso_8859() const33 std::string ASN1_EAC_String::iso_8859() const
34 {
35 return iso_8859_str;
36 }
37
38 /*
39 * Return this string in local encoding
40 */
value() const41 std::string ASN1_EAC_String::value() const
42 {
43 return Charset::transcode(iso_8859_str, LATIN1_CHARSET, LOCAL_CHARSET);
44 }
45
46 /*
47 * Return the type of this string object
48 */
tagging() const49 ASN1_Tag ASN1_EAC_String::tagging() const
50 {
51 return tag;
52 }
53
54 /*
55 * DER encode an ASN1_EAC_String
56 */
encode_into(DER_Encoder & encoder) const57 void ASN1_EAC_String::encode_into(DER_Encoder& encoder) const
58 {
59 std::string value = iso_8859();
60 encoder.add_object(tagging(), APPLICATION, value);
61 }
62
63 /*
64 * Decode a BER encoded ASN1_EAC_String
65 */
decode_from(BER_Decoder & source)66 void ASN1_EAC_String::decode_from(BER_Decoder& source)
67 {
68 BER_Object obj = source.get_next_object();
69
70 if(obj.type_tag != this->tag)
71 {
72 std::stringstream ss;
73
74 ss << "ASN1_EAC_String tag mismatch, tag was "
75 << std::hex << obj.type_tag
76 << " expected "
77 << std::hex << this->tag;
78
79 throw Decoding_Error(ss.str());
80 }
81
82 Character_Set charset_is;
83 charset_is = LATIN1_CHARSET;
84
85 try
86 {
87 *this = ASN1_EAC_String(
88 Charset::transcode(ASN1::to_string(obj), charset_is, LOCAL_CHARSET),
89 obj.type_tag);
90 }
91 catch(Invalid_Argument inv_arg)
92 {
93 throw Decoding_Error(std::string("ASN1_EAC_String decoding failed: ") +
94 inv_arg.what());
95 }
96 }
97
98 // checks for compliance to the alphabet defined in TR-03110 v1.10, 2007-08-20
99 // p. 43
sanity_check() const100 bool ASN1_EAC_String::sanity_check() const
101 {
102 const byte* rep = reinterpret_cast<const byte*>(iso_8859_str.data());
103 const size_t rep_len = iso_8859_str.size();
104
105 for(size_t i = 0; i != rep_len; ++i)
106 {
107 if((rep[i] < 0x20) || ((rep[i] >= 0x7F) && (rep[i] < 0xA0)))
108 return false;
109 }
110
111 return true;
112 }
113
operator ==(const ASN1_EAC_String & lhs,const ASN1_EAC_String & rhs)114 bool operator==(const ASN1_EAC_String& lhs, const ASN1_EAC_String& rhs)
115 {
116 return (lhs.iso_8859() == rhs.iso_8859());
117 }
118
ASN1_Car(std::string const & str)119 ASN1_Car::ASN1_Car(std::string const& str)
120 : ASN1_EAC_String(str, ASN1_Tag(2))
121 {}
122
ASN1_Chr(std::string const & str)123 ASN1_Chr::ASN1_Chr(std::string const& str)
124 : ASN1_EAC_String(str, ASN1_Tag(32))
125 {}
126
127 }
128