001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: /**
019: * @author Boris V. Kuznetsov
020: * @version $Revision$
021: */package java.security;
022:
023: import java.io.BufferedInputStream;
024: import java.io.File;
025: import java.io.FileInputStream;
026: import java.io.IOException;
027: import java.io.InputStream;
028: import java.util.Enumeration;
029: import java.net.URL;
030: import java.util.HashMap;
031: import java.util.HashSet;
032: import java.util.Iterator;
033: import java.util.Map;
034: import java.util.Properties;
035: import java.util.Set;
036:
037: import org.apache.harmony.security.Util;
038: import org.apache.harmony.security.fortress.Engine;
039: import org.apache.harmony.security.fortress.PolicyUtils;
040: import org.apache.harmony.security.fortress.SecurityAccess;
041: import org.apache.harmony.security.fortress.Services;
042: import org.apache.harmony.security.internal.nls.Messages;
043:
044: /**
045: * For access to security providers and properties.
046: */
047: public final class Security {
048:
049: // Security properties
050: private static Properties secprops = new Properties();
051:
052: // static initialization
053: // - load security properties files
054: // - load statically registered providers
055: // - if no provider description file found then load default providers
056: static {
057: AccessController
058: .doPrivileged(new java.security.PrivilegedAction<Void>() {
059: public Void run() {
060: boolean loaded = false;
061: File f = new File(
062: System.getProperty("java.home") //$NON-NLS-1$
063: + File.separator
064: + "lib" + File.separator //$NON-NLS-1$
065: + "security" + File.separator + "java.security"); //$NON-NLS-1$ //$NON-NLS-2$
066: if (f.exists()) {
067: try {
068: FileInputStream fis = new FileInputStream(
069: f);
070: InputStream is = new BufferedInputStream(
071: fis);
072: secprops.load(is);
073: loaded = true;
074: is.close();
075: } catch (IOException e) {
076: // System.err.println("Could not load Security properties file: "
077: // + e);
078: }
079: }
080:
081: if (Util
082: .equalsIgnoreCase(
083: "true", secprops.getProperty("security.allowCustomPropertiesFile", "true"))) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
084: String securityFile = System
085: .getProperty("java.security.properties"); //$NON-NLS-1$
086: if (securityFile != null) {
087: if (securityFile.startsWith("=")) { // overwrite //$NON-NLS-1$
088: secprops = new Properties();
089: loaded = false;
090: securityFile = securityFile
091: .substring(1);
092: }
093: try {
094: securityFile = PolicyUtils.expand(
095: securityFile, System
096: .getProperties());
097: } catch (PolicyUtils.ExpansionFailedException e) {
098: // System.err.println("Could not load custom Security properties file "
099: // + securityFile +": " + e);
100: }
101: f = new File(securityFile);
102: InputStream is;
103: try {
104: if (f.exists()) {
105: FileInputStream fis = new FileInputStream(
106: f);
107: is = new BufferedInputStream(
108: fis);
109: } else {
110: URL url = new URL(securityFile);
111: is = new BufferedInputStream(
112: url.openStream());
113: }
114: secprops.load(is);
115: loaded = true;
116: is.close();
117: } catch (IOException e) {
118: // System.err.println("Could not load custom Security properties file "
119: // + securityFile +": " + e);
120: }
121: }
122: }
123: if (!loaded) {
124: registerDefaultProviders();
125: }
126: Engine.door = new SecurityDoor();
127: return null;
128: }
129: });
130: }
131:
132: /**
133: * This class can't be instantiated.
134: */
135: private Security() {
136: }
137:
138: // Register default providers
139: private static void registerDefaultProviders() {
140: secprops
141: .put(
142: "security.provider.1", "org.apache.harmony.security.provider.cert.DRLCertFactory"); //$NON-NLS-1$ //$NON-NLS-2$
143: secprops
144: .put(
145: "security.provider.2", "org.apache.harmony.security.provider.crypto.CryptoProvider"); //$NON-NLS-1$ //$NON-NLS-2$
146: secprops
147: .put(
148: "security.provider.3", "org.apache.harmony.xnet.provider.jsse.JSSEProvider"); //$NON-NLS-1$ //$NON-NLS-2$
149: secprops
150: .put(
151: "security.provider.4", "org.bouncycastle.jce.provider.BouncyCastleProvider"); //$NON-NLS-1$ //$NON-NLS-2$
152: }
153:
154: /**
155: * Deprecated method which returns null.
156: * @param algName
157: * @param propName
158: * @return <code>null</code>
159: *
160: * @deprecated Use AlgorithmParameters and KeyFactory instead
161: */
162: @Deprecated
163: public static String getAlgorithmProperty(String algName,
164: String propName) {
165: if (algName == null || propName == null) {
166: return null;
167: }
168: String prop = propName + "." + algName; //$NON-NLS-1$
169: Provider[] providers = getProviders();
170: for (int i = 0; i < providers.length; i++) {
171: for (Enumeration e = providers[i].propertyNames(); e
172: .hasMoreElements();) {
173: String pname = (String) e.nextElement();
174: if (Util.equalsIgnoreCase(prop, pname)) {
175: return providers[i].getProperty(pname);
176: }
177: }
178: }
179: return null;
180: }
181:
182: /**
183: * @com.intel.drl.spec_ref
184: *
185: */
186: public static synchronized int insertProviderAt(Provider provider,
187: int position) {
188: // check security access; check that provider is not already
189: // installed, else return -1; if (position <1) or (position > max
190: // position) position = max position + 1; insert provider, shift up
191: // one position for next providers; Note: The position is 1-based
192: SecurityManager sm = System.getSecurityManager();
193: if (sm != null) {
194: sm
195: .checkSecurityAccess("insertProvider." + provider.getName()); //$NON-NLS-1$
196: }
197: if (getProvider(provider.getName()) != null) {
198: return -1;
199: }
200: int result = Services.insertProviderAt(provider, position);
201: renumProviders();
202: return result;
203: }
204:
205: /**
206: * Adds the extra provider to the collection of providers.
207: * @param provider
208: *
209: * @return int The priority/position of the provider added.
210: * @exception SecurityException
211: * If there is a SecurityManager installed and it denies
212: * adding a new provider.
213: */
214: public static int addProvider(Provider provider) {
215: return insertProviderAt(provider, 0);
216: }
217:
218: /**
219: * @com.intel.drl.spec_ref
220: *
221: */
222: public static synchronized void removeProvider(String name) {
223: // It is not clear from spec.:
224: // 1. if name is null, should we checkSecurityAccess or not?
225: // throw SecurityException or not?
226: // 2. as 1 but provider is not installed
227: // 3. behavior if name is empty string?
228:
229: Provider p;
230: if ((name == null) || (name.length() == 0)) {
231: return;
232: }
233: p = getProvider(name);
234: if (p == null) {
235: return;
236: }
237: SecurityManager sm = System.getSecurityManager();
238: if (sm != null) {
239: sm.checkSecurityAccess("removeProvider." + name); //$NON-NLS-1$
240: }
241: Services.removeProvider(p.getProviderNumber());
242: renumProviders();
243: p.setProviderNumber(-1);
244: }
245:
246: /**
247: * @com.intel.drl.spec_ref
248: *
249: */
250: public static synchronized Provider[] getProviders() {
251: return Services.getProviders();
252: }
253:
254: /**
255: * @com.intel.drl.spec_ref
256: *
257: */
258: public static synchronized Provider getProvider(String name) {
259: return Services.getProvider(name);
260: }
261:
262: /**
263: * Returns the collection of providers which meet the user supplied string
264: * filter.
265: *
266: * @param filter
267: * case-insensitive filter
268: * @return the providers which meet the user supplied string filter
269: * <code>filter</code>. A <code>null</code> value signifies
270: * that none of the installed providers meets the filter
271: * specification
272: * @exception InvalidParameterException
273: * if an unusable filter is supplied
274: */
275: public static Provider[] getProviders(String filter) {
276: if (filter == null) {
277: throw new NullPointerException(Messages
278: .getString("security.2A")); //$NON-NLS-1$
279: }
280: if (filter.length() == 0) {
281: throw new InvalidParameterException(Messages
282: .getString("security.2B")); //$NON-NLS-1$
283: }
284: HashMap<String, String> hm = new HashMap<String, String>();
285: int i = filter.indexOf(":"); //$NON-NLS-1$
286: if ((i == filter.length() - 1) || (i == 0)) {
287: throw new InvalidParameterException(Messages
288: .getString("security.2B")); //$NON-NLS-1$
289: }
290: if (i < 1) {
291: hm.put(filter, ""); //$NON-NLS-1$
292: } else {
293: hm.put(filter.substring(0, i), filter.substring(i + 1));
294: }
295: return getProviders(hm);
296: }
297:
298: /**
299: * @com.intel.drl.spec_ref
300: *
301: */
302: public static synchronized Provider[] getProviders(
303: Map<String, String> filter) {
304: if (filter == null) {
305: throw new NullPointerException(Messages
306: .getString("security.2A")); //$NON-NLS-1$
307: }
308: if (filter.isEmpty()) {
309: return null;
310: }
311: java.util.List<Provider> result = Services.getProvidersList();
312: Set keys = filter.entrySet();
313: Map.Entry entry;
314: for (Iterator it = keys.iterator(); it.hasNext();) {
315: entry = (Map.Entry) it.next();
316: String key = (String) entry.getKey();
317: String val = (String) entry.getValue();
318: String attribute = null;
319: int i = key.indexOf(" "); //$NON-NLS-1$
320: int j = key.indexOf("."); //$NON-NLS-1$
321: if (j == -1) {
322: throw new InvalidParameterException(Messages
323: .getString("security.2B")); //$NON-NLS-1$
324: }
325: if (i == -1) { // <crypto_service>.<algorithm_or_type>
326: if (val.length() != 0) {
327: throw new InvalidParameterException(Messages
328: .getString("security.2B")); //$NON-NLS-1$
329: }
330: } else { // <crypto_service>.<algorithm_or_type> <attribute_name>
331: if (val.length() == 0) {
332: throw new InvalidParameterException(Messages
333: .getString("security.2B")); //$NON-NLS-1$
334: }
335: attribute = key.substring(i + 1);
336: if (attribute.trim().length() == 0) {
337: throw new InvalidParameterException(Messages
338: .getString("security.2B")); //$NON-NLS-1$
339: }
340: key = key.substring(0, i);
341: }
342: String serv = key.substring(0, j);
343: String alg = key.substring(j + 1);
344: if (serv.length() == 0 || alg.length() == 0) {
345: throw new InvalidParameterException(Messages
346: .getString("security.2B")); //$NON-NLS-1$
347: }
348: Provider p;
349: for (int k = 0; k < result.size(); k++) {
350: try {
351: p = (Provider) result.get(k);
352: } catch (IndexOutOfBoundsException e) {
353: break;
354: }
355: if (!p.implements Alg(serv, alg, attribute, val)) {
356: result.remove(p);
357: k--;
358: }
359: }
360: }
361: if (result.size() > 0) {
362: return result.toArray(new Provider[result.size()]);
363: } else {
364: return null;
365: }
366: }
367:
368: /**
369: * Answers the value of the security property named by the argument.
370: *
371: *
372: * @param key
373: * String The property name
374: * @return String The property value
375: *
376: * @exception SecurityException
377: * If there is a SecurityManager installed and it will not
378: * allow the property to be fetched from the current access
379: * control context.
380: */
381: public static String getProperty(String key) {
382: if (key == null) {
383: throw new NullPointerException(Messages
384: .getString("security.2C")); //$NON-NLS-1$
385: }
386: SecurityManager sm = System.getSecurityManager();
387: if (sm != null) {
388: sm.checkSecurityAccess("getProperty." + key); //$NON-NLS-1$
389: }
390: return secprops.getProperty(key);
391: }
392:
393: /**
394: * Sets a given security property.
395: *
396: *
397: * @param key
398: * String The property name.
399: * @param datnum
400: * String The property value.
401: * @exception SecurityException
402: * If there is a SecurityManager installed and it will not
403: * allow the property to be set from the current access
404: * control context.
405: */
406: public static void setProperty(String key, String datnum) {
407: SecurityManager sm = System.getSecurityManager();
408: if (sm != null) {
409: sm.checkSecurityAccess("setProperty." + key); //$NON-NLS-1$
410: }
411: secprops.put(key, datnum);
412: }
413:
414: /**
415: * @com.intel.drl.spec_ref
416: *
417: */
418: public static Set<String> getAlgorithms(String serviceName) {
419: Set<String> result = new HashSet<String>();
420: Provider[] p = getProviders();
421: for (int i = 0; i < p.length; i++) {
422: for (Iterator it = p[i].getServices().iterator(); it
423: .hasNext();) {
424: Provider.Service s = (Provider.Service) it.next();
425: if (Util.equalsIgnoreCase(s.getType(), serviceName)) {
426: result.add(s.getAlgorithm());
427: }
428: }
429: }
430: return result;
431: }
432:
433: /**
434: *
435: * Update sequence numbers of all providers
436: *
437: */
438: private static void renumProviders() {
439: Provider[] p = Services.getProviders();
440: for (int i = 0; i < p.length; i++) {
441: p[i].setProviderNumber(i + 1);
442: }
443: }
444:
445: private static class SecurityDoor implements SecurityAccess {
446: // Access to Security.renumProviders()
447: public void renumProviders() {
448: Security.renumProviders();
449: }
450:
451: // Access to Security.getAliases()
452: public Iterator<String> getAliases(Provider.Service s) {
453: return s.getAliases();
454: }
455:
456: // Access to Provider.getService()
457: public Provider.Service getService(Provider p, String type) {
458: return p.getService(type);
459: }
460: }
461: }
|