001: /**
002: * Copyright (c) 2003-2005, www.pdfbox.org
003: * All rights reserved.
004: *
005: * Redistribution and use in source and binary forms, with or without
006: * modification, are permitted provided that the following conditions are met:
007: *
008: * 1. Redistributions of source code must retain the above copyright notice,
009: * this list of conditions and the following disclaimer.
010: * 2. Redistributions in binary form must reproduce the above copyright notice,
011: * this list of conditions and the following disclaimer in the documentation
012: * and/or other materials provided with the distribution.
013: * 3. Neither the name of pdfbox; nor the names of its
014: * contributors may be used to endorse or promote products derived from this
015: * software without specific prior written permission.
016: *
017: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
018: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
019: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
020: * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
021: * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
022: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
023: * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
024: * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
025: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
026: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
027: *
028: * http://www.pdfbox.org
029: *
030: */package org.pdfbox.pdmodel.encryption;
031:
032: import java.lang.reflect.Constructor;
033: import java.security.Security;
034: import java.util.Hashtable;
035:
036: import org.bouncycastle.jce.provider.BouncyCastleProvider;
037:
038: /**
039: * This class manages security handlers for the application. It follows the singleton pattern.
040: * To be usable, security managers must be registered in it. Security managers are retrieved by
041: * the application when necessary.
042: *
043: * @author Benoit Guillon (benoit.guillon@snv.jussieu.fr)
044: *
045: * @version $Revision: 1.3 $
046: *
047: */
048: public class SecurityHandlersManager {
049:
050: /**
051: * The unique instance of this manager.
052: */
053: private static SecurityHandlersManager instance;
054:
055: /**
056: * hashtable used to index handlers regarding their name.
057: * Basically this will be used when opening an encrypted
058: * document to find the appropriate security handler to handle
059: * security features of the document.
060: */
061: private Hashtable handlerNames = null;
062:
063: /**
064: * Hashtable used to index handlers regarding the class of
065: * protection policy they use. Basically this will be used when
066: * encrypting a document.
067: */
068: private Hashtable handlerPolicyClasses = null;
069:
070: /**
071: * private constructor.
072: */
073: private SecurityHandlersManager() {
074: handlerNames = new Hashtable();
075: handlerPolicyClasses = new Hashtable();
076: try {
077: this .registerHandler(StandardSecurityHandler.FILTER,
078: StandardSecurityHandler.class,
079: StandardProtectionPolicy.class);
080: this .registerHandler(PublicKeySecurityHandler.FILTER,
081: PublicKeySecurityHandler.class,
082: PublicKeyProtectionPolicy.class);
083: } catch (Exception e) {
084: System.err
085: .println("SecurityHandlersManager strange error with builtin handlers: "
086: + e.getMessage());
087: System.exit(1);
088: }
089: }
090:
091: /**
092: * register a security handler.
093: *
094: * If the security handler was already registered an exception is thrown.
095: * If another handler was previously registered for the same filter name or
096: * for the same policy name, an exception is thrown
097: *
098: * @param filterName The name of the filter.
099: * @param securityHandlerClass Security Handler class to register.
100: * @param protectionPolicyClass Protection Policy class to register.
101: *
102: * @throws BadSecurityHandlerException If there is an error registering the security handler.
103: */
104: public void registerHandler(String filterName,
105: Class securityHandlerClass, Class protectionPolicyClass)
106: throws BadSecurityHandlerException {
107: if (handlerNames.contains(securityHandlerClass)
108: || handlerPolicyClasses.contains(securityHandlerClass)) {
109: throw new BadSecurityHandlerException(
110: "the following security handler was already registered: "
111: + securityHandlerClass.getName());
112: }
113:
114: if (SecurityHandler.class
115: .isAssignableFrom(securityHandlerClass)) {
116: try {
117: if (handlerNames.containsKey(filterName)) {
118: throw new BadSecurityHandlerException(
119: "a security handler was already registered "
120: + "for the filter name "
121: + filterName);
122: }
123: if (handlerPolicyClasses
124: .containsKey(protectionPolicyClass)) {
125: throw new BadSecurityHandlerException(
126: "a security handler was already registered "
127: + "for the policy class "
128: + protectionPolicyClass.getName());
129: }
130:
131: handlerNames.put(filterName, securityHandlerClass);
132: handlerPolicyClasses.put(protectionPolicyClass,
133: securityHandlerClass);
134: } catch (Exception e) {
135: throw new BadSecurityHandlerException(e);
136: }
137: } else {
138: throw new BadSecurityHandlerException(
139: "The class is not a super class of SecurityHandler");
140: }
141: }
142:
143: /**
144: * Get the singleton instance.
145: *
146: * @return The SecurityHandlersManager.
147: */
148: public static SecurityHandlersManager getInstance() {
149: if (instance == null) {
150: instance = new SecurityHandlersManager();
151: }
152: Security.addProvider(new BouncyCastleProvider());
153:
154: return instance;
155: }
156:
157: /**
158: * Get the security handler for the protection policy.
159: *
160: * @param policy The policy to get the security handler for.
161: *
162: * @return The appropriate security handler.
163: *
164: * @throws BadSecurityHandlerException If it is unable to create a SecurityHandler.
165: */
166: public SecurityHandler getSecurityHandler(ProtectionPolicy policy)
167: throws BadSecurityHandlerException {
168:
169: Object found = handlerPolicyClasses.get(policy.getClass());
170: if (found == null) {
171: throw new BadSecurityHandlerException(
172: "Cannot find an appropriate security handler for "
173: + policy.getClass().getName());
174: }
175: Class handlerclass = (Class) found;
176: Class[] argsClasses = { policy.getClass() };
177: Object[] args = { policy };
178: try {
179: Constructor c = handlerclass
180: .getDeclaredConstructor(argsClasses);
181: SecurityHandler handler = (SecurityHandler) c
182: .newInstance(args);
183: return handler;
184: } catch (Exception e) {
185: e.printStackTrace();
186: throw new BadSecurityHandlerException(
187: "problem while trying to instanciate the security handler "
188: + handlerclass.getName() + ": "
189: + e.getMessage());
190: }
191: }
192:
193: /**
194: * Retrieve the appropriate SecurityHandler for a the given filter name.
195: * The filter name is an entry of the encryption dictionary of an encrypted document.
196: *
197: * @param filterName The filter name.
198: *
199: * @return The appropriate SecurityHandler if it exists.
200: *
201: * @throws BadSecurityHandlerException If the security handler does not exist.
202: */
203: public SecurityHandler getSecurityHandler(String filterName)
204: throws BadSecurityHandlerException {
205: Object found = handlerNames.get(filterName);
206: if (found == null) {
207: throw new BadSecurityHandlerException(
208: "Cannot find an appropriate security handler for "
209: + filterName);
210: }
211: Class handlerclass = (Class) found;
212: Class[] argsClasses = {};
213: Object[] args = {};
214: try {
215: Constructor c = handlerclass
216: .getDeclaredConstructor(argsClasses);
217: SecurityHandler handler = (SecurityHandler) c
218: .newInstance(args);
219: return handler;
220: } catch (Exception e) {
221: e.printStackTrace();
222: throw new BadSecurityHandlerException(
223: "problem while trying to instanciate the security handler "
224: + handlerclass.getName() + ": "
225: + e.getMessage());
226: }
227: }
228: }
|