001: /*
002: * Copyright (c) 2007, intarsys consulting GmbH
003: *
004: * Redistribution and use in source and binary forms, with or without
005: * modification, are permitted provided that the following conditions are met:
006: *
007: * - Redistributions of source code must retain the above copyright notice,
008: * this list of conditions and the following disclaimer.
009: *
010: * - 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: *
014: * - Neither the name of intarsys nor the names of its contributors may be used
015: * to endorse or promote products derived from this software without specific
016: * prior written permission.
017: *
018: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
019: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
020: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
021: * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
022: * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
023: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
024: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
025: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
026: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
027: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
028: * POSSIBILITY OF SUCH DAMAGE.
029: */
030: package de.intarsys.pdf.crypt;
031:
032: import java.util.HashMap;
033: import java.util.Map;
034:
035: import de.intarsys.pdf.cos.COSDictionary;
036: import de.intarsys.pdf.cos.COSInteger;
037: import de.intarsys.pdf.cos.COSName;
038: import de.intarsys.pdf.cos.COSObjectKey;
039: import de.intarsys.pdf.cos.COSStream;
040: import de.intarsys.pdf.filter.Filter;
041:
042: /**
043: * The {@link ISystemSecurityHandler} implementing /V 4 of the PDF spec.
044: *
045: */
046: public class SystemSecurityHandlerV4 extends SystemSecurityHandler {
047:
048: public static final COSName DK_NAME = COSName.constant("Name"); //$NON-NLS-1$
049:
050: public static final COSName CN_AESV2 = COSName.constant("AESV2"); //$NON-NLS-1$
051:
052: public static final COSName CN_None = COSName.constant("None"); //$NON-NLS-1$
053:
054: public static final COSName CN_V2 = COSName.constant("V2"); //$NON-NLS-1$
055:
056: public static final COSName DK_CFM = COSName.constant("CFM"); //$NON-NLS-1$
057:
058: private Map cryptHandlers = new HashMap();
059:
060: protected SystemSecurityHandlerV4(COSEncryption encryption) {
061: super (encryption);
062: }
063:
064: protected ICryptHandler createCryptHandler(COSName name)
065: throws COSSecurityException {
066: if (COSEncryption.CN_IDENTITY.equals(name)) {
067: // can't redefine...
068: return new IdentityCryptHandler();
069: }
070: COSDictionary dict = getEncryption().getCryptFilterDict(name);
071: if (dict == null) {
072: // can't redefine...
073: return new IdentityCryptHandler();
074: }
075: COSName method = dict.get(DK_CFM).asName();
076: if (CN_V2.equals(method)) {
077: StandardCryptHandler result = new ArcFourCryptHandler();
078: result.init(getSecurityHandler().getCryptKey());
079: return result;
080: }
081: if (CN_AESV2.equals(method)) {
082: StandardCryptHandler result = new AESCryptHandler();
083: result.init(getSecurityHandler().getCryptKey());
084: return result;
085: }
086: return getSecurityHandler();
087: }
088:
089: public byte[] decryptFile(COSObjectKey key, COSDictionary dict,
090: byte[] bytes) throws COSSecurityException {
091: COSName name = getEncryption().getCryptFilterNameFile();
092: ICryptHandler handler = getCryptHandler(name);
093: byte[] result = handler.decrypt(key, bytes);
094: return result;
095: }
096:
097: public byte[] decryptStream(COSObjectKey key, COSDictionary dict,
098: byte[] bytes) throws COSSecurityException {
099: COSName name = COSEncryption.CN_IDENTITY;
100: if (COSStream.hasFilter(dict, Filter.CN_Filter_Crypt)) {
101: COSDictionary decodeParams = COSStream.getDecodeParams(
102: dict, Filter.CN_Filter_Crypt);
103: if (decodeParams != null) {
104: COSName paramName = decodeParams.get(DK_NAME).asName();
105: if (paramName != null) {
106: name = paramName;
107: }
108: }
109: } else {
110: name = getEncryption().getCryptFilterNameString();
111: }
112: ICryptHandler handler = getCryptHandler(name);
113: byte[] result = handler.decrypt(key, bytes);
114: dict.put(COSStream.DK_Length, COSInteger.create(result.length));
115: return result;
116: }
117:
118: public byte[] decryptString(COSObjectKey key, byte[] bytes)
119: throws COSSecurityException {
120: COSName name = getEncryption().getCryptFilterNameString();
121: ICryptHandler handler = getCryptHandler(name);
122: return handler.decrypt(key, bytes);
123: }
124:
125: public byte[] encryptFile(COSObjectKey key, COSDictionary dict,
126: byte[] bytes) throws COSSecurityException {
127: COSName name = getEncryption().getCryptFilterNameFile();
128: ICryptHandler handler = getCryptHandler(name);
129: byte[] result = handler.encrypt(key, bytes);
130: return result;
131: }
132:
133: public byte[] encryptStream(COSObjectKey key, COSDictionary dict,
134: byte[] bytes) throws COSSecurityException {
135: COSName name = COSEncryption.CN_IDENTITY;
136: if (COSStream.hasFilter(dict, Filter.CN_Filter_Crypt)) {
137: COSDictionary decodeParams = COSStream.getDecodeParams(
138: dict, Filter.CN_Filter_Crypt);
139: if (decodeParams != null) {
140: COSName paramName = decodeParams.get(DK_NAME).asName();
141: if (paramName != null) {
142: name = paramName;
143: }
144: }
145: } else {
146: name = getEncryption().getCryptFilterNameString();
147: }
148: ICryptHandler handler = getCryptHandler(name);
149: byte[] result = handler.encrypt(key, bytes);
150: dict.put(COSStream.DK_Length, COSInteger.create(result.length));
151: return result;
152: }
153:
154: public byte[] encryptString(COSObjectKey key, byte[] bytes)
155: throws COSSecurityException {
156: COSName name = getEncryption().getCryptFilterNameString();
157: ICryptHandler handler = getCryptHandler(name);
158: return handler.encrypt(key, bytes);
159: }
160:
161: public ICryptHandler getCryptHandler(COSName name)
162: throws COSSecurityException {
163: ICryptHandler cryptHandler = (ICryptHandler) cryptHandlers
164: .get(name);
165: if (cryptHandler == null) {
166: cryptHandler = createCryptHandler(name);
167: cryptHandlers.put(name, cryptHandler);
168: }
169: return cryptHandler;
170: }
171:
172: }
|