1 11 package org.eclipse.osgi.internal.verifier; 12 13 import java.util.ArrayList ; 14 import javax.security.auth.x500.X500Principal ; 15 16 46 public class DNChainMatching { 47 54 private static boolean rdnmatch(ArrayList rdn, ArrayList rdnPattern) { 55 if (rdn.size() != rdnPattern.size()) 56 return false; 57 for (int i = 0; i < rdn.size(); i++) { 58 String rdnNameValue = (String ) rdn.get(i); 59 String patNameValue = (String ) rdnPattern.get(i); 60 int rdnNameEnd = rdnNameValue.indexOf('='); 61 int patNameEnd = patNameValue.indexOf('='); 62 if (rdnNameEnd != patNameEnd || !rdnNameValue.regionMatches(0, patNameValue, 0, rdnNameEnd)) { 63 return false; 64 } 65 String patValue = patNameValue.substring(patNameEnd); 66 String rdnValue = rdnNameValue.substring(rdnNameEnd); 67 if (!rdnValue.equals(patValue) && !patValue.equals("=*") && !patValue.equals("=#16012a")) { return false; 69 } 70 } 71 return true; 72 } 73 74 private static boolean dnmatch(ArrayList dn, ArrayList dnPattern) { 75 int dnStart = 0; 76 int patStart = 0; 77 int patLen = dnPattern.size(); 78 if (patLen == 0) { 79 return false; 80 } 81 if (dnPattern.get(0).equals("*")) { patStart = 1; 83 patLen--; 84 } 85 if (dn.size() < patLen) { 86 return false; 87 } else if (dn.size() > patLen) { 88 if (!dnPattern.get(0).equals("*")) { return false; 91 } 92 dnStart = dn.size() - patLen; 94 } 95 for (int i = 0; i < patLen; i++) { 96 if (!rdnmatch((ArrayList ) dn.get(i + dnStart), (ArrayList ) dnPattern.get(i + patStart))) { 97 return false; 98 } 99 } 100 return true; 101 } 102 103 116 private static ArrayList parseDNchain(String dnChain) throws IllegalArgumentException { 117 ArrayList parsed = new ArrayList (); 118 int startIndex = 0; 119 startIndex = skipSpaces(dnChain, startIndex); 120 while (startIndex < dnChain.length()) { 121 int endIndex = startIndex; 122 boolean inQuote = false; 123 out: while (endIndex < dnChain.length()) { 124 char c = dnChain.charAt(endIndex); 125 switch (c) { 126 case '"' : 127 inQuote = !inQuote; 128 break; 129 case '\\' : 130 endIndex++; break; 132 case ';' : 133 if (!inQuote) 134 break out; 135 } 136 endIndex++; 137 } 138 if (endIndex > dnChain.length()) { 139 throw new IllegalArgumentException ("unterminated escape"); } 141 parsed.add(dnChain.substring(startIndex, endIndex)); 142 startIndex = endIndex + 1; 143 startIndex = skipSpaces(dnChain, startIndex); 144 } 145 for (int i = 0; i < parsed.size(); i++) { 148 String dn = (String ) parsed.get(i); 149 if (dn.equals("*")) continue; 151 ArrayList rdns = new ArrayList (); 152 if (dn.charAt(0) == '*') { 153 if (dn.charAt(1) != ',') 154 throw new IllegalArgumentException ("invalid wildcard prefix"); rdns.add("*"); dn = new X500Principal (dn.substring(2)).getName(X500Principal.CANONICAL); 157 } else { 158 dn = new X500Principal (dn).getName(X500Principal.CANONICAL); 159 } 160 parseDN(dn, rdns); 162 parsed.set(i, rdns); 163 } 164 if (parsed.size() == 0) { 165 throw new IllegalArgumentException ("empty DN chain"); } 167 return parsed; 168 } 169 170 174 private static int skipSpaces(String dnChain, int startIndex) { 175 while (startIndex < dnChain.length() && dnChain.charAt(startIndex) == ' ') 176 startIndex++; 177 return startIndex; 178 } 179 180 188 private static void parseDN(String dn, ArrayList rdnArray) throws IllegalArgumentException { 189 int startIndex = 0; 190 char c = '\0'; 191 ArrayList nameValues = new ArrayList (); 192 while (startIndex < dn.length()) { 193 int endIndex; 194 for (endIndex = startIndex; endIndex < dn.length(); endIndex++) { 195 c = dn.charAt(endIndex); 196 if (c == ',' || c == '+') 197 break; 198 if (c == '\\') { 199 endIndex++; } 201 } 202 if (endIndex > dn.length()) 203 throw new IllegalArgumentException ("unterminated escape " + dn); nameValues.add(dn.substring(startIndex, endIndex)); 205 if (c != '+') { 206 rdnArray.add(nameValues); 207 if (endIndex != dn.length()) 208 nameValues = new ArrayList (); 209 else 210 nameValues = null; 211 } 212 startIndex = endIndex + 1; 213 } 214 if (nameValues != null) { 215 throw new IllegalArgumentException ("improperly terminated DN " + dn); } 217 } 218 219 223 private static int skipWildCards(ArrayList dnChainPattern, int dnChainPatternIndex) throws IllegalArgumentException { 224 int i; 225 for (i = dnChainPatternIndex; i < dnChainPattern.size(); i++) { 226 Object dnPattern = dnChainPattern.get(i); 227 if (dnPattern instanceof String ) { 228 if (!dnPattern.equals("*")) { throw new IllegalArgumentException ("expected wild-card in DN pattern"); } 231 } else if (dnPattern instanceof ArrayList ) { 233 break; 235 } else { 236 throw new IllegalArgumentException ("expected String or Arraylist in DN Pattern"); } 239 } 240 return i; 244 } 245 246 251 private static boolean dnChainMatch(ArrayList dnChain, int dnChainIndex, ArrayList dnChainPattern, int dnChainPatternIndex) throws IllegalArgumentException { 252 if (dnChainIndex >= dnChain.size()) { 253 return false; 254 } 255 if (dnChainPatternIndex >= dnChainPattern.size()) { 256 return false; 257 } 258 Object dnPattern = dnChainPattern.get(dnChainPatternIndex); 260 if (dnPattern instanceof String ) { 261 if (!dnPattern.equals("*")) { throw new IllegalArgumentException ("expected wild-card in DN pattern"); } 264 dnChainPatternIndex = skipWildCards(dnChainPattern, dnChainPatternIndex); 267 if (dnChainPatternIndex >= dnChainPattern.size()) { 268 return true; 270 } 271 for (int i = dnChainIndex; i < dnChain.size(); i++) { 277 if (dnChainMatch(dnChain, i, dnChainPattern, dnChainPatternIndex)) { 278 return true; 279 } 280 } 281 } else if (dnPattern instanceof ArrayList ) { 284 do { 287 if (!dnmatch((ArrayList ) dnChain.get(dnChainIndex), (ArrayList ) dnPattern)) { 288 return false; 289 } 290 dnChainIndex++; 292 dnChainPatternIndex++; 293 if ((dnChainIndex >= dnChain.size()) && (dnChainPatternIndex >= dnChainPattern.size())) { 295 return true; 296 } 297 if (dnChainIndex >= dnChain.size()) { 301 dnChainPatternIndex = skipWildCards(dnChainPattern, dnChainPatternIndex); 302 return (dnChainPatternIndex >= dnChainPattern.size()); 306 } 307 if (dnChainPatternIndex >= dnChainPattern.size()) { 310 return false; 311 } 312 dnPattern = dnChainPattern.get(dnChainPatternIndex); 314 if (dnPattern instanceof String ) { 315 if (!dnPattern.equals("*")) { throw new IllegalArgumentException ("expected wild-card in DN pattern"); } 318 return dnChainMatch(dnChain, dnChainIndex, dnChainPattern, dnChainPatternIndex); 320 } else if (!(dnPattern instanceof ArrayList )) { 321 throw new IllegalArgumentException ("expected String or Arraylist in DN Pattern"); } 323 } while (true); 327 } else { 329 throw new IllegalArgumentException ("expected String or Arraylist in DN Pattern"); } 331 return false; 333 } 334 335 363 public static boolean match(String dnChain, String pattern) { 364 ArrayList parsedDNChain; 365 ArrayList parsedDNPattern; 366 try { 367 parsedDNChain = parseDNchain(dnChain); 368 } catch (IllegalArgumentException e) { 369 System.err.println(e.getMessage() + ": " + dnChain); return false; 371 } 372 try { 373 parsedDNPattern = parseDNchain(pattern); 374 } catch (IllegalArgumentException e) { 375 System.err.println(e.getMessage() + ": " + pattern); return false; 377 } 378 try { 379 return dnChainMatch(parsedDNChain, 0, parsedDNPattern, 0); 380 } catch (Exception e) { 381 e.printStackTrace(); 382 } 383 return false; 384 } 385 } 386 | Popular Tags |