1/*
2Copyright (C) 1999-2007 The Botan Project. All rights reserved.
3
4Redistribution and use in source and binary forms, for any use, with or without
5modification, is permitted provided that the following conditions are met:
6
71. Redistributions of source code must retain the above copyright notice, this
8list of conditions, and the following disclaimer.
9
102. Redistributions in binary form must reproduce the above copyright notice,
11this list of conditions, and the following disclaimer in the documentation
12and/or other materials provided with the distribution.
13
14THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) "AS IS" AND ANY EXPRESS OR IMPLIED
15WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
17
18IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE FOR ANY DIRECT,
19INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
20BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
22LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
23OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
24ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25*/
26// LICENSEHEADER_END
27namespace QCA { // WRAPNS_LINE
28/*************************************************
29 * Parser Functions Source File *
30 * (C) 1999-2007 The Botan Project *
31 *************************************************/
32
33} // WRAPNS_LINE
34#include <botan/parsing.h>
35namespace QCA { // WRAPNS_LINE
36} // WRAPNS_LINE
37#include <botan/exceptn.h>
38namespace QCA { // WRAPNS_LINE
39} // WRAPNS_LINE
40#include <botan/charset.h>
41namespace QCA { // WRAPNS_LINE
42
43namespace Botan {
44
45/*************************************************
46 * Convert a string into an integer *
47 *************************************************/
48#ifndef BOTAN_TOOLS_ONLY
49u32bit to_u32bit(const std::string &number)
50{
51 u32bit n = 0;
52
53 for (std::string::const_iterator j = number.begin(); j != number.end(); ++j) {
54 const u32bit OVERFLOW_MARK = 0xFFFFFFFF / 10;
55
56 byte digit = Charset::char2digit(*j);
57
58 if ((n > OVERFLOW_MARK) || (n == OVERFLOW_MARK && digit > 5))
59 throw Decoding_Error("to_u32bit: Integer overflow");
60 n *= 10;
61 n += digit;
62 }
63 return n;
64}
65#endif
66
67/*************************************************
68 * Convert an integer into a string *
69 *************************************************/
70std::string to_string(u64bit n, u32bit min_len)
71{
72 std::string lenstr;
73 if (n) {
74 while (n > 0) {
75 lenstr = Charset::digit2char(n % 10) + lenstr; // NOLINT(performance-inefficient-string-concatenation)
76 n /= 10;
77 }
78 } else
79 lenstr = "0";
80
81 while (lenstr.size() < min_len)
82 lenstr = "0" + lenstr; // NOLINT(performance-inefficient-string-concatenation)
83
84 return lenstr;
85}
86
87#ifndef BOTAN_TOOLS_ONLY
88/*************************************************
89 * Parse a SCAN-style algorithm name *
90 *************************************************/
91std::vector<std::string> parse_algorithm_name(const std::string &namex)
92{
93 if (namex.find('(') == std::string::npos && namex.find(')') == std::string::npos)
94 return std::vector<std::string>(1, namex);
95
96 std::string name = namex, substring;
97 std::vector<std::string> elems;
98 u32bit level = 0;
99
100 elems.push_back(name.substr(0, name.find('(')));
101 name = name.substr(name.find('('));
102
103 for (std::string::const_iterator j = name.begin(); j != name.end(); ++j) {
104 char c = *j;
105
106 if (c == '(')
107 ++level;
108 if (c == ')') {
109 if (level == 1 && j == name.end() - 1) {
110 if (elems.size() == 1)
111 elems.push_back(substring.substr(1));
112 else
113 elems.push_back(substring);
114 return elems;
115 }
116
117 if (level == 0 || (level == 1 && j != name.end() - 1))
118 throw Invalid_Algorithm_Name(namex);
119 --level;
120 }
121
122 if (c == ',' && level == 1) {
123 if (elems.size() == 1)
124 elems.push_back(substring.substr(1));
125 else
126 elems.push_back(substring);
127 substring.clear();
128 } else
129 substring += c;
130 }
131
132 if (substring != "")
133 throw Invalid_Algorithm_Name(namex);
134
135 return elems;
136}
137
138/*************************************************
139 * Split the string on slashes *
140 *************************************************/
141std::vector<std::string> split_on(const std::string &str, char delim)
142{
143 std::vector<std::string> elems;
144 if (str == "")
145 return elems;
146
147 std::string substr;
148 for (std::string::const_iterator j = str.begin(); j != str.end(); ++j) {
149 if (*j == delim) {
150 if (substr != "")
151 elems.push_back(substr);
152 substr.clear();
153 } else
154 substr += *j;
155 }
156
157 if (substr == "")
158 throw Format_Error("Unable to split string: " + str);
159 elems.push_back(substr);
160
161 return elems;
162}
163
164/*************************************************
165 * Parse an ASN.1 OID string *
166 *************************************************/
167std::vector<u32bit> parse_asn1_oid(const std::string &oid)
168{
169 std::string substring;
170 std::vector<u32bit> oid_elems;
171
172 for (std::string::const_iterator j = oid.begin(); j != oid.end(); ++j) {
173 char c = *j;
174
175 if (c == '.') {
176 if (substring == "")
177 throw Invalid_OID(oid);
178 oid_elems.push_back(to_u32bit(substring));
179 substring.clear();
180 } else
181 substring += c;
182 }
183
184 if (substring == "")
185 throw Invalid_OID(oid);
186 oid_elems.push_back(to_u32bit(substring));
187
188 if (oid_elems.size() < 2)
189 throw Invalid_OID(oid);
190
191 return oid_elems;
192}
193
194/*************************************************
195 * X.500 String Comparison *
196 *************************************************/
197bool x500_name_cmp(const std::string &name1, const std::string &name2)
198{
199 std::string::const_iterator p1 = name1.begin();
200 std::string::const_iterator p2 = name2.begin();
201
202 while ((p1 != name1.end()) && Charset::is_space(*p1))
203 ++p1;
204 while ((p2 != name2.end()) && Charset::is_space(*p2))
205 ++p2;
206
207 while (p1 != name1.end() && p2 != name2.end()) {
208 if (Charset::is_space(*p1)) {
209 if (!Charset::is_space(*p2))
210 return false;
211
212 while ((p1 != name1.end()) && Charset::is_space(*p1))
213 ++p1;
214 while ((p2 != name2.end()) && Charset::is_space(*p2))
215 ++p2;
216
217 if (p1 == name1.end() && p2 == name2.end())
218 return true;
219 }
220
221 if (!Charset::caseless_cmp(*p1, *p2))
222 return false;
223 ++p1;
224 ++p2;
225 }
226
227 while ((p1 != name1.end()) && Charset::is_space(*p1))
228 ++p1;
229 while ((p2 != name2.end()) && Charset::is_space(*p2))
230 ++p2;
231
232 if ((p1 != name1.end()) || (p2 != name2.end()))
233 return false;
234 return true;
235}
236
237/*************************************************
238 * Parse and compute an arithmetic expression *
239 *************************************************/
240u32bit parse_expr(const std::string &expr)
241{
242 const bool have_add = (expr.find('+') != std::string::npos);
243 const bool have_mul = (expr.find('*') != std::string::npos);
244
245 if (have_add) {
246 std::vector<std::string> sub_expr = split_on(expr, '+');
247 u32bit result = 0;
248 for (u32bit j = 0; j != sub_expr.size(); ++j)
249 result += parse_expr(sub_expr[j]);
250 return result;
251 } else if (have_mul) {
252 std::vector<std::string> sub_expr = split_on(expr, '*');
253 u32bit result = 1;
254 for (u32bit j = 0; j != sub_expr.size(); ++j)
255 result *= parse_expr(sub_expr[j]);
256 return result;
257 } else
258 return to_u32bit(expr);
259}
260#endif
261
262}
263} // WRAPNS_LINE
264

source code of qca/src/botantools/botan/parsing.cpp