00001
00002
00003
00004
00005
00006
00007
00008 #include <botan/asn1_obj.h>
00009 #include <botan/der_enc.h>
00010 #include <botan/ber_dec.h>
00011 #include <botan/charset.h>
00012 #include <botan/parsing.h>
00013
00014 namespace Botan {
00015
00016 namespace {
00017
00018
00019
00020
00021 ASN1_Tag choose_encoding(const std::string& str,
00022 const std::string& type)
00023 {
00024 static const byte IS_PRINTABLE[256] = {
00025 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00026 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00027 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
00028 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,
00029 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00,
00030 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
00031 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
00032 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
00033 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
00034 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
00035 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00036 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00037 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00038 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00039 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00040 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00041 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00042 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00043 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00044 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00045 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00046 0x00, 0x00, 0x00, 0x00 };
00047
00048 for(u32bit j = 0; j != str.size(); ++j)
00049 {
00050 if(!IS_PRINTABLE[static_cast<byte>(str[j])])
00051 {
00052 if(type == "utf8") return UTF8_STRING;
00053 if(type == "latin1") return T61_STRING;
00054 throw Invalid_Argument("choose_encoding: Bad string type " + type);
00055 }
00056 }
00057 return PRINTABLE_STRING;
00058 }
00059
00060 }
00061
00062
00063
00064
00065 bool is_string_type(ASN1_Tag tag)
00066 {
00067 if(tag == NUMERIC_STRING || tag == PRINTABLE_STRING ||
00068 tag == VISIBLE_STRING || tag == T61_STRING || tag == IA5_STRING ||
00069 tag == UTF8_STRING || tag == BMP_STRING)
00070 return true;
00071 return false;
00072 }
00073
00074
00075
00076
00077 ASN1_String::ASN1_String(const std::string& str, ASN1_Tag t) : tag(t)
00078 {
00079 iso_8859_str = Charset::transcode(str, LOCAL_CHARSET, LATIN1_CHARSET);
00080
00081 if(tag == DIRECTORY_STRING)
00082 tag = choose_encoding(iso_8859_str, "latin1");
00083
00084 if(tag != NUMERIC_STRING &&
00085 tag != PRINTABLE_STRING &&
00086 tag != VISIBLE_STRING &&
00087 tag != T61_STRING &&
00088 tag != IA5_STRING &&
00089 tag != UTF8_STRING &&
00090 tag != BMP_STRING)
00091 throw Invalid_Argument("ASN1_String: Unknown string type " +
00092 to_string(tag));
00093 }
00094
00095
00096
00097
00098 ASN1_String::ASN1_String(const std::string& str)
00099 {
00100 iso_8859_str = Charset::transcode(str, LOCAL_CHARSET, LATIN1_CHARSET);
00101 tag = choose_encoding(iso_8859_str, "latin1");
00102 }
00103
00104
00105
00106
00107 std::string ASN1_String::iso_8859() const
00108 {
00109 return iso_8859_str;
00110 }
00111
00112
00113
00114
00115 std::string ASN1_String::value() const
00116 {
00117 return Charset::transcode(iso_8859_str, LATIN1_CHARSET, LOCAL_CHARSET);
00118 }
00119
00120
00121
00122
00123 ASN1_Tag ASN1_String::tagging() const
00124 {
00125 return tag;
00126 }
00127
00128
00129
00130
00131 void ASN1_String::encode_into(DER_Encoder& encoder) const
00132 {
00133 std::string value = iso_8859();
00134 if(tagging() == UTF8_STRING)
00135 value = Charset::transcode(value, LATIN1_CHARSET, UTF8_CHARSET);
00136 encoder.add_object(tagging(), UNIVERSAL, value);
00137 }
00138
00139
00140
00141
00142 void ASN1_String::decode_from(BER_Decoder& source)
00143 {
00144 BER_Object obj = source.get_next_object();
00145
00146 Character_Set charset_is;
00147
00148 if(obj.type_tag == BMP_STRING)
00149 charset_is = UCS2_CHARSET;
00150 else if(obj.type_tag == UTF8_STRING)
00151 charset_is = UTF8_CHARSET;
00152 else
00153 charset_is = LATIN1_CHARSET;
00154
00155 *this = ASN1_String(
00156 Charset::transcode(ASN1::to_string(obj), charset_is, LOCAL_CHARSET),
00157 obj.type_tag);
00158 }
00159
00160 }