1 /* 2 * reserved comment block 3 * DO NOT REMOVE OR ALTER! 4 */ 5 /** 6 * Licensed to the Apache Software Foundation (ASF) under one 7 * or more contributor license agreements. See the NOTICE file 8 * distributed with this work for additional information 9 * regarding copyright ownership. The ASF licenses this file 10 * to you under the Apache License, Version 2.0 (the 11 * "License"); you may not use this file except in compliance 12 * with the License. You may obtain a copy of the License at 13 * 14 * http://www.apache.org/licenses/LICENSE-2.0 15 * 16 * Unless required by applicable law or agreed to in writing, 17 * software distributed under the License is distributed on an 18 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 19 * KIND, either express or implied. See the License for the 20 * specific language governing permissions and limitations 21 * under the License. 22 */ 23 package com.sun.org.apache.xml.internal.security; 24 25 import java.io.InputStream; 26 import java.security.AccessController; 27 import java.security.PrivilegedAction; 28 import java.util.ArrayList; 29 import java.util.List; 30 31 import javax.xml.XMLConstants; 32 import javax.xml.parsers.DocumentBuilder; 33 import javax.xml.parsers.DocumentBuilderFactory; 34 35 import com.sun.org.apache.xml.internal.security.algorithms.JCEMapper; 36 import com.sun.org.apache.xml.internal.security.algorithms.SignatureAlgorithm; 37 import com.sun.org.apache.xml.internal.security.c14n.Canonicalizer; 38 import com.sun.org.apache.xml.internal.security.keys.keyresolver.KeyResolver; 39 import com.sun.org.apache.xml.internal.security.transforms.Transform; 40 import com.sun.org.apache.xml.internal.security.utils.ElementProxy; 41 import com.sun.org.apache.xml.internal.security.utils.I18n; 42 import com.sun.org.apache.xml.internal.security.utils.XMLUtils; 43 import com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolver; 44 import org.w3c.dom.Attr; 45 import org.w3c.dom.Document; 46 import org.w3c.dom.Element; 47 import org.w3c.dom.Node; 48 49 50 /** 51 * This class does the configuration of the library. This includes creating 52 * the mapping of Canonicalization and Transform algorithms. Initialization is 53 * done by calling {@link Init#init} which should be done in any static block 54 * of the files of this library. We ensure that this call is only executed once. 55 */ 56 public class Init { 57 58 /** The namespace for CONF file **/ 59 public static final String CONF_NS = "http://www.xmlsecurity.org/NS/#configuration"; 60 61 /** {@link org.apache.commons.logging} logging facility */ 62 private static java.util.logging.Logger log = 63 java.util.logging.Logger.getLogger(Init.class.getName()); 64 65 /** Field alreadyInitialized */ 66 private static boolean alreadyInitialized = false; 67 68 /** 69 * Method isInitialized 70 * @return true if the library is already initialized. 71 */ 72 public static synchronized final boolean isInitialized() { 73 return Init.alreadyInitialized; 74 } 75 76 /** 77 * Method init 78 * 79 */ 80 public static synchronized void init() { 81 if (alreadyInitialized) { 82 return; 83 } 84 85 InputStream is = 86 AccessController.doPrivileged( 87 new PrivilegedAction<InputStream>() { 88 public InputStream run() { 89 String cfile = 90 System.getProperty("com.sun.org.apache.xml.internal.security.resource.config"); 91 if (cfile == null) { 92 return null; 93 } 94 return getClass().getResourceAsStream(cfile); 95 } 96 }); 97 if (is == null) { 98 dynamicInit(); 99 } else { 100 fileInit(is); 101 } 102 103 alreadyInitialized = true; 104 } 105 106 /** 107 * Dynamically initialise the library by registering the default algorithms/implementations 108 */ 109 private static void dynamicInit() { 110 // 111 // Load the Resource Bundle - the default is the English resource bundle. 112 // To load another resource bundle, call I18n.init(...) before calling this 113 // method. 114 // 115 I18n.init("en", "US"); 116 117 if (log.isLoggable(java.util.logging.Level.FINE)) { 118 log.log(java.util.logging.Level.FINE, "Registering default algorithms"); 119 } 120 try { 121 // 122 // Bind the default prefixes 123 // 124 ElementProxy.registerDefaultPrefixes(); 125 126 // 127 // Set the default Transforms 128 // 129 Transform.registerDefaultAlgorithms(); 130 131 // 132 // Set the default signature algorithms 133 // 134 SignatureAlgorithm.registerDefaultAlgorithms(); 135 136 // 137 // Set the default JCE algorithms 138 // 139 JCEMapper.registerDefaultAlgorithms(); 140 141 // 142 // Set the default c14n algorithms 143 // 144 Canonicalizer.registerDefaultAlgorithms(); 145 146 // 147 // Register the default resolvers 148 // 149 ResourceResolver.registerDefaultResolvers(); 150 151 // 152 // Register the default key resolvers 153 // 154 KeyResolver.registerDefaultResolvers(); 155 } catch (Exception ex) { 156 log.log(java.util.logging.Level.SEVERE, ex.getMessage(), ex); 157 ex.printStackTrace(); 158 } 159 } 160 161 /** 162 * Initialise the library from a configuration file 163 */ 164 private static void fileInit(InputStream is) { 165 try { 166 /* read library configuration file */ 167 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 168 dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, Boolean.TRUE); 169 170 dbf.setNamespaceAware(true); 171 dbf.setValidating(false); 172 173 DocumentBuilder db = dbf.newDocumentBuilder(); 174 Document doc = db.parse(is); 175 Node config = doc.getFirstChild(); 176 for (; config != null; config = config.getNextSibling()) { 177 if ("Configuration".equals(config.getLocalName())) { 178 break; 179 } 180 } 181 if (config == null) { 182 log.log(java.util.logging.Level.SEVERE, "Error in reading configuration file - Configuration element not found"); 183 return; 184 } 185 for (Node el = config.getFirstChild(); el != null; el = el.getNextSibling()) { 186 if (Node.ELEMENT_NODE != el.getNodeType()) { 187 continue; 188 } 189 String tag = el.getLocalName(); 190 if (tag.equals("ResourceBundles")) { 191 Element resource = (Element)el; 192 /* configure internationalization */ 193 Attr langAttr = resource.getAttributeNode("defaultLanguageCode"); 194 Attr countryAttr = resource.getAttributeNode("defaultCountryCode"); 195 String languageCode = 196 (langAttr == null) ? null : langAttr.getNodeValue(); 197 String countryCode = 198 (countryAttr == null) ? null : countryAttr.getNodeValue(); 199 I18n.init(languageCode, countryCode); 200 } 201 202 if (tag.equals("CanonicalizationMethods")) { 203 Element[] list = 204 XMLUtils.selectNodes(el.getFirstChild(), CONF_NS, "CanonicalizationMethod"); 205 206 for (int i = 0; i < list.length; i++) { 207 String uri = list[i].getAttributeNS(null, "URI"); 208 String javaClass = 209 list[i].getAttributeNS(null, "JAVACLASS"); 210 try { 211 Canonicalizer.register(uri, javaClass); 212 if (log.isLoggable(java.util.logging.Level.FINE)) { 213 log.log(java.util.logging.Level.FINE, "Canonicalizer.register(" + uri + ", " + javaClass + ")"); 214 } 215 } catch (ClassNotFoundException e) { 216 Object exArgs[] = { uri, javaClass }; 217 log.log(java.util.logging.Level.SEVERE, I18n.translate("algorithm.classDoesNotExist", exArgs)); 218 } 219 } 220 } 221 222 if (tag.equals("TransformAlgorithms")) { 223 Element[] tranElem = 224 XMLUtils.selectNodes(el.getFirstChild(), CONF_NS, "TransformAlgorithm"); 225 226 for (int i = 0; i < tranElem.length; i++) { 227 String uri = tranElem[i].getAttributeNS(null, "URI"); 228 String javaClass = 229 tranElem[i].getAttributeNS(null, "JAVACLASS"); 230 try { 231 Transform.register(uri, javaClass); 232 if (log.isLoggable(java.util.logging.Level.FINE)) { 233 log.log(java.util.logging.Level.FINE, "Transform.register(" + uri + ", " + javaClass + ")"); 234 } 235 } catch (ClassNotFoundException e) { 236 Object exArgs[] = { uri, javaClass }; 237 238 log.log(java.util.logging.Level.SEVERE, I18n.translate("algorithm.classDoesNotExist", exArgs)); 239 } catch (NoClassDefFoundError ex) { 240 log.log(java.util.logging.Level.WARNING, "Not able to found dependencies for algorithm, I'll keep working."); 241 } 242 } 243 } 244 245 if ("JCEAlgorithmMappings".equals(tag)) { 246 Node algorithmsNode = ((Element)el).getElementsByTagName("Algorithms").item(0); 247 if (algorithmsNode != null) { 248 Element[] algorithms = 249 XMLUtils.selectNodes(algorithmsNode.getFirstChild(), CONF_NS, "Algorithm"); 250 for (int i = 0; i < algorithms.length; i++) { 251 Element element = algorithms[i]; 252 String id = element.getAttribute("URI"); 253 JCEMapper.register(id, new JCEMapper.Algorithm(element)); 254 } 255 } 256 } 257 258 if (tag.equals("SignatureAlgorithms")) { 259 Element[] sigElems = 260 XMLUtils.selectNodes(el.getFirstChild(), CONF_NS, "SignatureAlgorithm"); 261 262 for (int i = 0; i < sigElems.length; i++) { 263 String uri = sigElems[i].getAttributeNS(null, "URI"); 264 String javaClass = 265 sigElems[i].getAttributeNS(null, "JAVACLASS"); 266 267 /** $todo$ handle registering */ 268 269 try { 270 SignatureAlgorithm.register(uri, javaClass); 271 if (log.isLoggable(java.util.logging.Level.FINE)) { 272 log.log(java.util.logging.Level.FINE, "SignatureAlgorithm.register(" + uri + ", " 273 + javaClass + ")"); 274 } 275 } catch (ClassNotFoundException e) { 276 Object exArgs[] = { uri, javaClass }; 277 278 log.log(java.util.logging.Level.SEVERE, I18n.translate("algorithm.classDoesNotExist", exArgs)); 279 } 280 } 281 } 282 283 if (tag.equals("ResourceResolvers")) { 284 Element[]resolverElem = 285 XMLUtils.selectNodes(el.getFirstChild(), CONF_NS, "Resolver"); 286 287 for (int i = 0; i < resolverElem.length; i++) { 288 String javaClass = 289 resolverElem[i].getAttributeNS(null, "JAVACLASS"); 290 String description = 291 resolverElem[i].getAttributeNS(null, "DESCRIPTION"); 292 293 if ((description != null) && (description.length() > 0)) { 294 if (log.isLoggable(java.util.logging.Level.FINE)) { 295 log.log(java.util.logging.Level.FINE, "Register Resolver: " + javaClass + ": " 296 + description); 297 } 298 } else { 299 if (log.isLoggable(java.util.logging.Level.FINE)) { 300 log.log(java.util.logging.Level.FINE, "Register Resolver: " + javaClass 301 + ": For unknown purposes"); 302 } 303 } 304 try { 305 ResourceResolver.register(javaClass); 306 } catch (Throwable e) { 307 log.log(java.util.logging.Level.WARNING, 308 "Cannot register:" + javaClass 309 + " perhaps some needed jars are not installed", 310 e 311 ); 312 } 313 } 314 } 315 316 if (tag.equals("KeyResolver")){ 317 Element[] resolverElem = 318 XMLUtils.selectNodes(el.getFirstChild(), CONF_NS, "Resolver"); 319 List<String> classNames = new ArrayList<String>(resolverElem.length); 320 for (int i = 0; i < resolverElem.length; i++) { 321 String javaClass = 322 resolverElem[i].getAttributeNS(null, "JAVACLASS"); 323 String description = 324 resolverElem[i].getAttributeNS(null, "DESCRIPTION"); 325 326 if ((description != null) && (description.length() > 0)) { 327 if (log.isLoggable(java.util.logging.Level.FINE)) { 328 log.log(java.util.logging.Level.FINE, "Register Resolver: " + javaClass + ": " 329 + description); 330 } 331 } else { 332 if (log.isLoggable(java.util.logging.Level.FINE)) { 333 log.log(java.util.logging.Level.FINE, "Register Resolver: " + javaClass 334 + ": For unknown purposes"); 335 } 336 } 337 classNames.add(javaClass); 338 } 339 KeyResolver.registerClassNames(classNames); 340 } 341 342 343 if (tag.equals("PrefixMappings")){ 344 if (log.isLoggable(java.util.logging.Level.FINE)) { 345 log.log(java.util.logging.Level.FINE, "Now I try to bind prefixes:"); 346 } 347 348 Element[] nl = 349 XMLUtils.selectNodes(el.getFirstChild(), CONF_NS, "PrefixMapping"); 350 351 for (int i = 0; i < nl.length; i++) { 352 String namespace = nl[i].getAttributeNS(null, "namespace"); 353 String prefix = nl[i].getAttributeNS(null, "prefix"); 354 if (log.isLoggable(java.util.logging.Level.FINE)) { 355 log.log(java.util.logging.Level.FINE, "Now I try to bind " + prefix + " to " + namespace); 356 } 357 ElementProxy.setDefaultPrefix(namespace, prefix); 358 } 359 } 360 } 361 } catch (Exception e) { 362 log.log(java.util.logging.Level.SEVERE, "Bad: ", e); 363 e.printStackTrace(); 364 } 365 } 366 367 } 368