org.apache.pdfbox.pdmodel.encryption.SecurityHandlersManager Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of pdfbox Show documentation
Show all versions of pdfbox Show documentation
The Apache PDFBox library is an open source Java tool for working with PDF documents.
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.pdfbox.pdmodel.encryption;
import java.lang.reflect.Constructor;
import java.security.Security;
import java.util.Hashtable;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
/**
* This class manages security handlers for the application. It follows the singleton pattern.
* To be usable, security managers must be registered in it. Security managers are retrieved by
* the application when necessary.
*
* @author Benoit Guillon ([email protected])
*
* @version $Revision: 1.3 $
*
*/
public class SecurityHandlersManager
{
/**
* Log instance.
*/
private static final Log LOG = LogFactory.getLog(SecurityHandlersManager.class);
/**
* The unique instance of this manager.
*/
private static SecurityHandlersManager instance;
/**
* hashtable used to index handlers regarding their name.
* Basically this will be used when opening an encrypted
* document to find the appropriate security handler to handle
* security features of the document.
*/
private Hashtable handlerNames = null;
/**
* Hashtable used to index handlers regarding the class of
* protection policy they use. Basically this will be used when
* encrypting a document.
*/
private Hashtable handlerPolicyClasses = null;
/**
* private constructor.
*/
private SecurityHandlersManager()
{
handlerNames = new Hashtable();
handlerPolicyClasses = new Hashtable();
try
{
this.registerHandler(
StandardSecurityHandler.FILTER,
StandardSecurityHandler.class,
StandardProtectionPolicy.class);
this.registerHandler(
PublicKeySecurityHandler.FILTER,
PublicKeySecurityHandler.class,
PublicKeyProtectionPolicy.class);
}
catch (BadSecurityHandlerException e)
{
// should never happen
throw new RuntimeException(e);
}
}
/**
* register a security handler.
*
* If the security handler was already registered an exception is thrown.
* If another handler was previously registered for the same filter name or
* for the same policy name, an exception is thrown
*
* @param filterName The name of the filter.
* @param securityHandlerClass Security Handler class to register.
* @param protectionPolicyClass Protection Policy class to register.
*
* @throws BadSecurityHandlerException If there is an error registering the security handler.
*/
public void registerHandler(String filterName, Class securityHandlerClass, Class protectionPolicyClass)
throws BadSecurityHandlerException
{
if(handlerNames.contains(securityHandlerClass) || handlerPolicyClasses.contains(securityHandlerClass))
{
throw new BadSecurityHandlerException("the following security handler was already registered: " +
securityHandlerClass.getName());
}
if(SecurityHandler.class.isAssignableFrom(securityHandlerClass))
{
try
{
if(handlerNames.containsKey(filterName))
{
throw new BadSecurityHandlerException("a security handler was already registered " +
"for the filter name " + filterName);
}
if(handlerPolicyClasses.containsKey(protectionPolicyClass))
{
throw new BadSecurityHandlerException("a security handler was already registered " +
"for the policy class " + protectionPolicyClass.getName());
}
handlerNames.put(filterName, securityHandlerClass);
handlerPolicyClasses.put(protectionPolicyClass, securityHandlerClass);
}
catch(Exception e)
{
throw new BadSecurityHandlerException(e);
}
}
else
{
throw new BadSecurityHandlerException("The class is not a super class of SecurityHandler");
}
}
/**
* Get the singleton instance.
*
* @return The SecurityHandlersManager.
*/
public static SecurityHandlersManager getInstance()
{
if(instance == null)
{
instance = new SecurityHandlersManager();
Security.addProvider(new BouncyCastleProvider());
}
return instance;
}
/**
* Get the security handler for the protection policy.
*
* @param policy The policy to get the security handler for.
*
* @return The appropriate security handler.
*
* @throws BadSecurityHandlerException If it is unable to create a SecurityHandler.
*/
public SecurityHandler getSecurityHandler(ProtectionPolicy policy) throws BadSecurityHandlerException
{
Object found = handlerPolicyClasses.get(policy.getClass());
if(found == null)
{
throw new BadSecurityHandlerException(
"Cannot find an appropriate security handler for " + policy.getClass().getName());
}
Class handlerclass = (Class) found;
Class[] argsClasses = {policy.getClass()};
Object[] args = {policy};
try
{
Constructor c = handlerclass.getDeclaredConstructor(argsClasses);
SecurityHandler handler = (SecurityHandler)c.newInstance(args);
return handler;
}
catch(Exception e)
{
LOG.error(e,e);
throw new BadSecurityHandlerException(
"problem while trying to instanciate the security handler "+
handlerclass.getName() + ": " + e.getMessage());
}
}
/**
* Retrieve the appropriate SecurityHandler for a the given filter name.
* The filter name is an entry of the encryption dictionary of an encrypted document.
*
* @param filterName The filter name.
*
* @return The appropriate SecurityHandler if it exists.
*
* @throws BadSecurityHandlerException If the security handler does not exist.
*/
public SecurityHandler getSecurityHandler(String filterName) throws BadSecurityHandlerException
{
Object found = handlerNames.get(filterName);
if(found == null)
{
throw new BadSecurityHandlerException("Cannot find an appropriate security handler for " + filterName);
}
Class handlerclass = (Class) found;
Class[] argsClasses = {};
Object[] args = {};
try
{
Constructor c = handlerclass.getDeclaredConstructor(argsClasses);
SecurityHandler handler = (SecurityHandler)c.newInstance(args);
return handler;
}
catch(Exception e)
{
LOG.error(e,e);
throw new BadSecurityHandlerException(
"problem while trying to instanciate the security handler "+
handlerclass.getName() + ": " + e.getMessage());
}
}
}