1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.ws.security.util;
20
21 import java.io.IOException;
22 import java.io.StringReader;
23
24 public class RFC2253Parser {
25
26
27
28
29
30
31
32 public static String rfc2253toXMLdsig(String dn) {
33
34 String normalized = normalize(dn, true);
35
36 return rfctoXML(normalized);
37 }
38
39
40
41
42
43
44
45 public static String xmldsigtoRFC2253(String dn) {
46
47 String normalized = normalize(dn, false);
48
49 return xmltoRFC(normalized);
50 }
51
52
53
54
55
56
57
58 public static String normalize(String dn) {
59 return normalize(dn, true);
60 }
61
62
63
64
65
66
67
68
69 public static String normalize(String dn, boolean toXml) {
70
71 if ((dn == null) || dn.equals("")) {
72 return "";
73 }
74
75 try {
76 String DN = semicolonToComma(dn);
77 StringBuilder sb = new StringBuilder();
78 int i = 0;
79 int l = 0;
80 int k;
81
82
83 for (int j = 0; (k = DN.indexOf(',', j)) >= 0; j = k + 1) {
84 l += countQuotes(DN, j, k);
85
86 if ((k > 0) && (DN.charAt(k - 1) != '\\') && (l % 2) == 0) {
87 sb.append(parseRDN(DN.substring(i, k).trim(), toXml)).append(",");
88
89 i = k + 1;
90 l = 0;
91 }
92 }
93
94 sb.append(parseRDN(trim(DN.substring(i)), toXml));
95
96 return sb.toString();
97 } catch (IOException ex) {
98 return dn;
99 }
100 }
101
102
103
104
105
106
107
108
109
110 static String parseRDN(String str, boolean toXml) throws IOException {
111 StringBuilder sb = new StringBuilder();
112 int i = 0;
113 int l = 0;
114 int k;
115
116 for (int j = 0; (k = str.indexOf('+', j)) >= 0; j = k + 1) {
117 l += countQuotes(str, j, k);
118
119 if ((k > 0) && (str.charAt(k - 1) != '\\') && (l % 2) == 0) {
120 sb.append(parseATAV(trim(str.substring(i, k)), toXml)).append("+");
121
122 i = k + 1;
123 l = 0;
124 }
125 }
126
127 sb.append(parseATAV(trim(str.substring(i)), toXml));
128
129 return sb.toString();
130 }
131
132
133
134
135
136
137
138
139
140 static String parseATAV(String str, boolean toXml) throws IOException {
141 int i = str.indexOf('=');
142
143 if ((i == -1) || ((i > 0) && (str.charAt(i - 1) == '\\'))) {
144 return str;
145 }
146 String attrType = normalizeAT(str.substring(0, i));
147
148 String attrValue = null;
149 if (attrType.charAt(0) >= '0' && attrType.charAt(0) <= '9') {
150 attrValue = str.substring(i + 1);
151 } else {
152 attrValue = normalizeV(str.substring(i + 1), toXml);
153 }
154
155 return attrType + "=" + attrValue;
156
157 }
158
159
160
161
162
163
164
165 static String normalizeAT(String str) {
166
167 String at = str.toUpperCase().trim();
168
169 if (at.startsWith("OID")) {
170 at = at.substring(3);
171 }
172
173 return at;
174 }
175
176
177
178
179
180
181
182
183
184 static String normalizeV(String str, boolean toXml) throws IOException {
185 String value = trim(str);
186
187 if (value.startsWith("\"")) {
188 StringBuilder sb = new StringBuilder();
189 StringReader sr = new StringReader(value.substring(1, value.length() - 1));
190 int i = 0;
191 char c;
192
193 while ((i = sr.read()) > -1) {
194 c = (char) i;
195
196
197 if ((c == ',') || (c == '=') || (c == '+') || (c == '<')
198 || (c == '>') || (c == '#') || (c == ';')) {
199 sb.append('\\');
200 }
201
202 sb.append(c);
203 }
204
205 value = trim(sb.toString());
206 }
207
208 if (toXml) {
209 if (value.startsWith("#")) {
210 value = '\\' + value;
211 }
212 } else {
213 if (value.startsWith("\\#")) {
214 value = value.substring(1);
215 }
216 }
217
218 return value;
219 }
220
221
222
223
224
225
226
227 static String rfctoXML(String string) {
228 try {
229 String s = changeLess32toXML(string);
230
231 return changeWStoXML(s);
232 } catch (Exception e) {
233 return string;
234 }
235 }
236
237
238
239
240
241
242
243 static String xmltoRFC(String string) {
244 try {
245 String s = changeLess32toRFC(string);
246
247 return changeWStoRFC(s);
248 } catch (Exception e) {
249 return string;
250 }
251 }
252
253
254
255
256
257
258
259
260 static String changeLess32toRFC(String string) throws IOException {
261 StringBuilder sb = new StringBuilder();
262 StringReader sr = new StringReader(string);
263 int i = 0;
264 char c;
265
266 while ((i = sr.read()) > -1) {
267 c = (char) i;
268
269 if (c == '\\') {
270 sb.append(c);
271
272 char c1 = (char) sr.read();
273 char c2 = (char) sr.read();
274
275
276 if ((((c1 >= 48) && (c1 <= 57)) || ((c1 >= 65) && (c1 <= 70)) || ((c1 >= 97) && (c1 <= 102)))
277 && (((c2 >= 48) && (c2 <= 57))
278 || ((c2 >= 65) && (c2 <= 70))
279 || ((c2 >= 97) && (c2 <= 102)))) {
280 char ch = (char) Byte.parseByte("" + c1 + c2, 16);
281
282 sb.append(ch);
283 } else {
284 sb.append(c1);
285 sb.append(c2);
286 }
287 } else {
288 sb.append(c);
289 }
290 }
291
292 return sb.toString();
293 }
294
295
296
297
298
299
300
301
302 static String changeLess32toXML(String string) throws IOException {
303 StringBuilder sb = new StringBuilder();
304 StringReader sr = new StringReader(string);
305 int i = 0;
306
307 while ((i = sr.read()) > -1) {
308 if (i < 32) {
309 sb.append('\\');
310 sb.append(Integer.toHexString(i));
311 } else {
312 sb.append((char) i);
313 }
314 }
315
316 return sb.toString();
317 }
318
319
320
321
322
323
324
325
326 static String changeWStoXML(String string) throws IOException {
327 StringBuilder sb = new StringBuilder();
328 StringReader sr = new StringReader(string);
329 int i = 0;
330 char c;
331
332 while ((i = sr.read()) > -1) {
333 c = (char) i;
334
335 if (c == '\\') {
336 char c1 = (char) sr.read();
337
338 if (c1 == ' ') {
339 sb.append('\\');
340
341 String s = "20";
342
343 sb.append(s);
344 } else {
345 sb.append('\\');
346 sb.append(c1);
347 }
348 } else {
349 sb.append(c);
350 }
351 }
352
353 return sb.toString();
354 }
355
356
357
358
359
360
361
362 static String changeWStoRFC(String string) {
363 StringBuilder sb = new StringBuilder();
364 int i = 0;
365 int k;
366
367 for (int j = 0; (k = string.indexOf("\\20", j)) >= 0; j = k + 3) {
368 sb.append(trim(string.substring(i, k))).append("\\ ");
369
370 i = k + 3;
371 }
372
373 sb.append(string.substring(i));
374
375 return sb.toString();
376 }
377
378
379
380
381
382
383
384 static String semicolonToComma(String str) {
385 return removeWSandReplace(str, ";", ",");
386 }
387
388
389
390
391
392
393
394
395 static String removeWhiteSpace(String str, String symbol) {
396 return removeWSandReplace(str, symbol, symbol);
397 }
398
399
400
401
402
403
404
405
406
407 static String removeWSandReplace(String str, String symbol, String replace) {
408 StringBuilder sb = new StringBuilder();
409 int i = 0;
410 int l = 0;
411 int k;
412
413 for (int j = 0; (k = str.indexOf(symbol, j)) >= 0; j = k + 1) {
414 l += countQuotes(str, j, k);
415
416 if ((k > 0) && (str.charAt(k - 1) != '\\') && (l % 2) == 0) {
417 sb.append(trim(str.substring(i, k))).append(replace);
418
419 i = k + 1;
420 l = 0;
421 }
422 }
423
424 sb.append(trim(str.substring(i)));
425
426 return sb.toString();
427 }
428
429
430
431
432
433
434
435
436
437 private static int countQuotes(String s, int i, int j) {
438 int k = 0;
439
440 for (int l = i; l < j; l++) {
441 if (s.charAt(l) == '"') {
442 k++;
443 }
444 }
445
446 return k;
447 }
448
449
450
451
452
453
454
455
456
457 static String trim(String str) {
458
459 String trimed = str.trim();
460 int i = str.indexOf(trimed) + trimed.length();
461
462 if ((str.length() > i) && trimed.endsWith("\\")
463 && !trimed.endsWith("\\\\") && (str.charAt(i) == ' ')) {
464 trimed = trimed + " ";
465 }
466
467 return trimed;
468 }
469
470 }