00001
00002
00003
00004
00005
00006
00007
00008 #include <botan/parsing.h>
00009 #include <botan/exceptn.h>
00010 #include <botan/charset.h>
00011 #include <botan/get_byte.h>
00012
00013 namespace Botan {
00014
00015
00016
00017
00018 u32bit to_u32bit(const std::string& number)
00019 {
00020 u32bit n = 0;
00021
00022 for(std::string::const_iterator j = number.begin(); j != number.end(); ++j)
00023 {
00024 const u32bit OVERFLOW_MARK = 0xFFFFFFFF / 10;
00025
00026 if(*j == ' ')
00027 continue;
00028
00029 byte digit = Charset::char2digit(*j);
00030
00031 if((n > OVERFLOW_MARK) || (n == OVERFLOW_MARK && digit > 5))
00032 throw Decoding_Error("to_u32bit: Integer overflow");
00033 n *= 10;
00034 n += digit;
00035 }
00036 return n;
00037 }
00038
00039
00040
00041
00042 std::string to_string(u64bit n, u32bit min_len)
00043 {
00044 std::string lenstr;
00045 if(n)
00046 {
00047 while(n > 0)
00048 {
00049 lenstr = Charset::digit2char(n % 10) + lenstr;
00050 n /= 10;
00051 }
00052 }
00053 else
00054 lenstr = "0";
00055
00056 while(lenstr.size() < min_len)
00057 lenstr = "0" + lenstr;
00058
00059 return lenstr;
00060 }
00061
00062
00063
00064
00065 u32bit timespec_to_u32bit(const std::string& timespec)
00066 {
00067 if(timespec == "")
00068 return 0;
00069
00070 const char suffix = timespec[timespec.size()-1];
00071 std::string value = timespec.substr(0, timespec.size()-1);
00072
00073 u32bit scale = 1;
00074
00075 if(Charset::is_digit(suffix))
00076 value += suffix;
00077 else if(suffix == 's')
00078 scale = 1;
00079 else if(suffix == 'm')
00080 scale = 60;
00081 else if(suffix == 'h')
00082 scale = 60 * 60;
00083 else if(suffix == 'd')
00084 scale = 24 * 60 * 60;
00085 else if(suffix == 'y')
00086 scale = 365 * 24 * 60 * 60;
00087 else
00088 throw Decoding_Error("timespec_to_u32bit: Bad input " + timespec);
00089
00090 return scale * to_u32bit(value);
00091 }
00092
00093
00094
00095
00096 std::vector<std::string> parse_algorithm_name(const std::string& namex)
00097 {
00098 if(namex.find('(') == std::string::npos &&
00099 namex.find(')') == std::string::npos)
00100 return std::vector<std::string>(1, namex);
00101
00102 std::string name = namex, substring;
00103 std::vector<std::string> elems;
00104 u32bit level = 0;
00105
00106 elems.push_back(name.substr(0, name.find('(')));
00107 name = name.substr(name.find('('));
00108
00109 for(std::string::const_iterator j = name.begin(); j != name.end(); ++j)
00110 {
00111 char c = *j;
00112
00113 if(c == '(')
00114 ++level;
00115 if(c == ')')
00116 {
00117 if(level == 1 && j == name.end() - 1)
00118 {
00119 if(elems.size() == 1)
00120 elems.push_back(substring.substr(1));
00121 else
00122 elems.push_back(substring);
00123 return elems;
00124 }
00125
00126 if(level == 0 || (level == 1 && j != name.end() - 1))
00127 throw Invalid_Algorithm_Name(namex);
00128 --level;
00129 }
00130
00131 if(c == ',' && level == 1)
00132 {
00133 if(elems.size() == 1)
00134 elems.push_back(substring.substr(1));
00135 else
00136 elems.push_back(substring);
00137 substring.clear();
00138 }
00139 else
00140 substring += c;
00141 }
00142
00143 if(substring != "")
00144 throw Invalid_Algorithm_Name(namex);
00145
00146 return elems;
00147 }
00148
00149
00150
00151
00152 std::vector<std::string> split_on(const std::string& str, char delim)
00153 {
00154 std::vector<std::string> elems;
00155 if(str == "") return elems;
00156
00157 std::string substr;
00158 for(std::string::const_iterator j = str.begin(); j != str.end(); ++j)
00159 {
00160 if(*j == delim)
00161 {
00162 if(substr != "")
00163 elems.push_back(substr);
00164 substr.clear();
00165 }
00166 else
00167 substr += *j;
00168 }
00169
00170 if(substr == "")
00171 throw Invalid_Argument("Unable to split string: " + str);
00172 elems.push_back(substr);
00173
00174 return elems;
00175 }
00176
00177
00178
00179
00180 std::vector<u32bit> parse_asn1_oid(const std::string& oid)
00181 {
00182 std::string substring;
00183 std::vector<u32bit> oid_elems;
00184
00185 for(std::string::const_iterator j = oid.begin(); j != oid.end(); ++j)
00186 {
00187 char c = *j;
00188
00189 if(c == '.')
00190 {
00191 if(substring == "")
00192 throw Invalid_OID(oid);
00193 oid_elems.push_back(to_u32bit(substring));
00194 substring.clear();
00195 }
00196 else
00197 substring += c;
00198 }
00199
00200 if(substring == "")
00201 throw Invalid_OID(oid);
00202 oid_elems.push_back(to_u32bit(substring));
00203
00204 if(oid_elems.size() < 2)
00205 throw Invalid_OID(oid);
00206
00207 return oid_elems;
00208 }
00209
00210
00211
00212
00213 bool x500_name_cmp(const std::string& name1, const std::string& name2)
00214 {
00215 std::string::const_iterator p1 = name1.begin();
00216 std::string::const_iterator p2 = name2.begin();
00217
00218 while((p1 != name1.end()) && Charset::is_space(*p1)) ++p1;
00219 while((p2 != name2.end()) && Charset::is_space(*p2)) ++p2;
00220
00221 while(p1 != name1.end() && p2 != name2.end())
00222 {
00223 if(Charset::is_space(*p1))
00224 {
00225 if(!Charset::is_space(*p2))
00226 return false;
00227
00228 while((p1 != name1.end()) && Charset::is_space(*p1)) ++p1;
00229 while((p2 != name2.end()) && Charset::is_space(*p2)) ++p2;
00230
00231 if(p1 == name1.end() && p2 == name2.end())
00232 return true;
00233 }
00234
00235 if(!Charset::caseless_cmp(*p1, *p2))
00236 return false;
00237 ++p1;
00238 ++p2;
00239 }
00240
00241 while((p1 != name1.end()) && Charset::is_space(*p1)) ++p1;
00242 while((p2 != name2.end()) && Charset::is_space(*p2)) ++p2;
00243
00244 if((p1 != name1.end()) || (p2 != name2.end()))
00245 return false;
00246 return true;
00247 }
00248
00249
00250
00251
00252 u32bit string_to_ipv4(const std::string& str)
00253 {
00254 std::vector<std::string> parts = split_on(str, '.');
00255
00256 if(parts.size() != 4)
00257 throw Decoding_Error("Invalid IP string " + str);
00258
00259 u32bit ip = 0;
00260
00261 for(size_t j = 0; j != parts.size(); j++)
00262 {
00263 u32bit octet = to_u32bit(parts[j]);
00264
00265 if(octet > 255)
00266 throw Decoding_Error("Invalid IP string " + str);
00267
00268 ip = (ip << 8) | (octet & 0xFF);
00269 }
00270
00271 return ip;
00272 }
00273
00274
00275
00276
00277 std::string ipv4_to_string(u32bit ip)
00278 {
00279 std::string str;
00280
00281 for(size_t j = 0; j != sizeof(ip); j++)
00282 {
00283 if(j)
00284 str += ".";
00285 str += to_string(get_byte(j, ip));
00286 }
00287
00288 return str;
00289 }
00290
00291 }