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