Botan
1.11.15
|
00001 /* 00002 * Simple ASN.1 String Types 00003 * (C) 1999-2007 Jack Lloyd 00004 * 00005 * Botan is released under the Simplified BSD License (see license.txt) 00006 */ 00007 00008 #include <botan/asn1_str.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 * Choose an encoding for the string 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(size_t i = 0; i != str.size(); ++i) 00049 { 00050 if(!IS_PRINTABLE[static_cast<byte>(str[i])]) 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 * Create an ASN1_String 00064 */ 00065 ASN1_String::ASN1_String(const std::string& str, ASN1_Tag t) : tag(t) 00066 { 00067 iso_8859_str = Charset::transcode(str, LOCAL_CHARSET, LATIN1_CHARSET); 00068 00069 if(tag == DIRECTORY_STRING) 00070 tag = choose_encoding(iso_8859_str, "latin1"); 00071 00072 if(tag != NUMERIC_STRING && 00073 tag != PRINTABLE_STRING && 00074 tag != VISIBLE_STRING && 00075 tag != T61_STRING && 00076 tag != IA5_STRING && 00077 tag != UTF8_STRING && 00078 tag != BMP_STRING) 00079 throw Invalid_Argument("ASN1_String: Unknown string type " + 00080 std::to_string(tag)); 00081 } 00082 00083 /* 00084 * Create an ASN1_String 00085 */ 00086 ASN1_String::ASN1_String(const std::string& str) 00087 { 00088 iso_8859_str = Charset::transcode(str, LOCAL_CHARSET, LATIN1_CHARSET); 00089 tag = choose_encoding(iso_8859_str, "latin1"); 00090 } 00091 00092 /* 00093 * Return this string in ISO 8859-1 encoding 00094 */ 00095 std::string ASN1_String::iso_8859() const 00096 { 00097 return iso_8859_str; 00098 } 00099 00100 /* 00101 * Return this string in local encoding 00102 */ 00103 std::string ASN1_String::value() const 00104 { 00105 return Charset::transcode(iso_8859_str, LATIN1_CHARSET, LOCAL_CHARSET); 00106 } 00107 00108 /* 00109 * Return the type of this string object 00110 */ 00111 ASN1_Tag ASN1_String::tagging() const 00112 { 00113 return tag; 00114 } 00115 00116 /* 00117 * DER encode an ASN1_String 00118 */ 00119 void ASN1_String::encode_into(DER_Encoder& encoder) const 00120 { 00121 std::string value = iso_8859(); 00122 if(tagging() == UTF8_STRING) 00123 value = Charset::transcode(value, LATIN1_CHARSET, UTF8_CHARSET); 00124 encoder.add_object(tagging(), UNIVERSAL, value); 00125 } 00126 00127 /* 00128 * Decode a BER encoded ASN1_String 00129 */ 00130 void ASN1_String::decode_from(BER_Decoder& source) 00131 { 00132 BER_Object obj = source.get_next_object(); 00133 00134 Character_Set charset_is; 00135 00136 if(obj.type_tag == BMP_STRING) 00137 charset_is = UCS2_CHARSET; 00138 else if(obj.type_tag == UTF8_STRING) 00139 charset_is = UTF8_CHARSET; 00140 else 00141 charset_is = LATIN1_CHARSET; 00142 00143 *this = ASN1_String( 00144 Charset::transcode(ASN1::to_string(obj), charset_is, LOCAL_CHARSET), 00145 obj.type_tag); 00146 } 00147 00148 }