File indexing completed on 2024-05-12 04:45:15
0001 /* 0002 Copyright (C) 1999-2007 The Botan Project. All rights reserved. 0003 0004 Redistribution and use in source and binary forms, for any use, with or without 0005 modification, is permitted provided that the following conditions are met: 0006 0007 1. Redistributions of source code must retain the above copyright notice, this 0008 list of conditions, and the following disclaimer. 0009 0010 2. Redistributions in binary form must reproduce the above copyright notice, 0011 this list of conditions, and the following disclaimer in the documentation 0012 and/or other materials provided with the distribution. 0013 0014 THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) "AS IS" AND ANY EXPRESS OR IMPLIED 0015 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 0016 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED. 0017 0018 IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE FOR ANY DIRECT, 0019 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 0020 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 0021 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 0022 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 0023 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 0024 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 0025 */ 0026 // LICENSEHEADER_END 0027 namespace QCA { // WRAPNS_LINE 0028 /************************************************* 0029 * Parser Functions Source File * 0030 * (C) 1999-2007 The Botan Project * 0031 *************************************************/ 0032 0033 } // WRAPNS_LINE 0034 #include <botan/parsing.h> 0035 namespace QCA { // WRAPNS_LINE 0036 } // WRAPNS_LINE 0037 #include <botan/exceptn.h> 0038 namespace QCA { // WRAPNS_LINE 0039 } // WRAPNS_LINE 0040 #include <botan/charset.h> 0041 namespace QCA { // WRAPNS_LINE 0042 0043 namespace Botan { 0044 0045 /************************************************* 0046 * Convert a string into an integer * 0047 *************************************************/ 0048 #ifndef BOTAN_TOOLS_ONLY 0049 u32bit to_u32bit(const std::string &number) 0050 { 0051 u32bit n = 0; 0052 0053 for (std::string::const_iterator j = number.begin(); j != number.end(); ++j) { 0054 const u32bit OVERFLOW_MARK = 0xFFFFFFFF / 10; 0055 0056 byte digit = Charset::char2digit(*j); 0057 0058 if ((n > OVERFLOW_MARK) || (n == OVERFLOW_MARK && digit > 5)) 0059 throw Decoding_Error("to_u32bit: Integer overflow"); 0060 n *= 10; 0061 n += digit; 0062 } 0063 return n; 0064 } 0065 #endif 0066 0067 /************************************************* 0068 * Convert an integer into a string * 0069 *************************************************/ 0070 std::string to_string(u64bit n, u32bit min_len) 0071 { 0072 std::string lenstr; 0073 if (n) { 0074 while (n > 0) { 0075 lenstr = Charset::digit2char(n % 10) + lenstr; // NOLINT(performance-inefficient-string-concatenation) 0076 n /= 10; 0077 } 0078 } else 0079 lenstr = "0"; 0080 0081 while (lenstr.size() < min_len) 0082 lenstr = "0" + lenstr; // NOLINT(performance-inefficient-string-concatenation) 0083 0084 return lenstr; 0085 } 0086 0087 #ifndef BOTAN_TOOLS_ONLY 0088 /************************************************* 0089 * Parse a SCAN-style algorithm name * 0090 *************************************************/ 0091 std::vector<std::string> parse_algorithm_name(const std::string &namex) 0092 { 0093 if (namex.find('(') == std::string::npos && namex.find(')') == std::string::npos) 0094 return std::vector<std::string>(1, namex); 0095 0096 std::string name = namex, substring; 0097 std::vector<std::string> elems; 0098 u32bit level = 0; 0099 0100 elems.push_back(name.substr(0, name.find('('))); 0101 name = name.substr(name.find('(')); 0102 0103 for (std::string::const_iterator j = name.begin(); j != name.end(); ++j) { 0104 char c = *j; 0105 0106 if (c == '(') 0107 ++level; 0108 if (c == ')') { 0109 if (level == 1 && j == name.end() - 1) { 0110 if (elems.size() == 1) 0111 elems.push_back(substring.substr(1)); 0112 else 0113 elems.push_back(substring); 0114 return elems; 0115 } 0116 0117 if (level == 0 || (level == 1 && j != name.end() - 1)) 0118 throw Invalid_Algorithm_Name(namex); 0119 --level; 0120 } 0121 0122 if (c == ',' && level == 1) { 0123 if (elems.size() == 1) 0124 elems.push_back(substring.substr(1)); 0125 else 0126 elems.push_back(substring); 0127 substring.clear(); 0128 } else 0129 substring += c; 0130 } 0131 0132 if (substring != "") 0133 throw Invalid_Algorithm_Name(namex); 0134 0135 return elems; 0136 } 0137 0138 /************************************************* 0139 * Split the string on slashes * 0140 *************************************************/ 0141 std::vector<std::string> split_on(const std::string &str, char delim) 0142 { 0143 std::vector<std::string> elems; 0144 if (str == "") 0145 return elems; 0146 0147 std::string substr; 0148 for (std::string::const_iterator j = str.begin(); j != str.end(); ++j) { 0149 if (*j == delim) { 0150 if (substr != "") 0151 elems.push_back(substr); 0152 substr.clear(); 0153 } else 0154 substr += *j; 0155 } 0156 0157 if (substr == "") 0158 throw Format_Error("Unable to split string: " + str); 0159 elems.push_back(substr); 0160 0161 return elems; 0162 } 0163 0164 /************************************************* 0165 * Parse an ASN.1 OID string * 0166 *************************************************/ 0167 std::vector<u32bit> parse_asn1_oid(const std::string &oid) 0168 { 0169 std::string substring; 0170 std::vector<u32bit> oid_elems; 0171 0172 for (std::string::const_iterator j = oid.begin(); j != oid.end(); ++j) { 0173 char c = *j; 0174 0175 if (c == '.') { 0176 if (substring == "") 0177 throw Invalid_OID(oid); 0178 oid_elems.push_back(to_u32bit(substring)); 0179 substring.clear(); 0180 } else 0181 substring += c; 0182 } 0183 0184 if (substring == "") 0185 throw Invalid_OID(oid); 0186 oid_elems.push_back(to_u32bit(substring)); 0187 0188 if (oid_elems.size() < 2) 0189 throw Invalid_OID(oid); 0190 0191 return oid_elems; 0192 } 0193 0194 /************************************************* 0195 * X.500 String Comparison * 0196 *************************************************/ 0197 bool x500_name_cmp(const std::string &name1, const std::string &name2) 0198 { 0199 std::string::const_iterator p1 = name1.begin(); 0200 std::string::const_iterator p2 = name2.begin(); 0201 0202 while ((p1 != name1.end()) && Charset::is_space(*p1)) 0203 ++p1; 0204 while ((p2 != name2.end()) && Charset::is_space(*p2)) 0205 ++p2; 0206 0207 while (p1 != name1.end() && p2 != name2.end()) { 0208 if (Charset::is_space(*p1)) { 0209 if (!Charset::is_space(*p2)) 0210 return false; 0211 0212 while ((p1 != name1.end()) && Charset::is_space(*p1)) 0213 ++p1; 0214 while ((p2 != name2.end()) && Charset::is_space(*p2)) 0215 ++p2; 0216 0217 if (p1 == name1.end() && p2 == name2.end()) 0218 return true; 0219 } 0220 0221 if (!Charset::caseless_cmp(*p1, *p2)) 0222 return false; 0223 ++p1; 0224 ++p2; 0225 } 0226 0227 while ((p1 != name1.end()) && Charset::is_space(*p1)) 0228 ++p1; 0229 while ((p2 != name2.end()) && Charset::is_space(*p2)) 0230 ++p2; 0231 0232 if ((p1 != name1.end()) || (p2 != name2.end())) 0233 return false; 0234 return true; 0235 } 0236 0237 /************************************************* 0238 * Parse and compute an arithmetic expression * 0239 *************************************************/ 0240 u32bit parse_expr(const std::string &expr) 0241 { 0242 const bool have_add = (expr.find('+') != std::string::npos); 0243 const bool have_mul = (expr.find('*') != std::string::npos); 0244 0245 if (have_add) { 0246 std::vector<std::string> sub_expr = split_on(expr, '+'); 0247 u32bit result = 0; 0248 for (u32bit j = 0; j != sub_expr.size(); ++j) 0249 result += parse_expr(sub_expr[j]); 0250 return result; 0251 } else if (have_mul) { 0252 std::vector<std::string> sub_expr = split_on(expr, '*'); 0253 u32bit result = 1; 0254 for (u32bit j = 0; j != sub_expr.size(); ++j) 0255 result *= parse_expr(sub_expr[j]); 0256 return result; 0257 } else 0258 return to_u32bit(expr); 0259 } 0260 #endif 0261 0262 } 0263 } // WRAPNS_LINE