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.io.IOException;
033:
034: import org.pdfbox.cos.COSArray;
035: import org.pdfbox.cos.COSDictionary;
036: import org.pdfbox.cos.COSName;
037: import org.pdfbox.cos.COSString;
038:
039: /**
040: * This class is a specialized view of the encryption dictionary of a PDF document.
041: * It contains a low level dictionary (COSDictionary) and provides the methods to
042: * manage its fields.
043: *
044: * The available fields are the ones who are involved by standard security handler
045: * and public key security handler.
046: *
047: * @author <a href="mailto:ben@benlitchfield.com">Ben Litchfield</a>
048: * @author Benoit Guillon (benoit.guillon@snv.jussieu.fr)
049: *
050: * @version $Revision: 1.7 $
051: */
052: public class PDEncryptionDictionary {
053: /**
054: * See PDF Reference 1.4 Table 3.13.
055: */
056: public static final int VERSION0_UNDOCUMENTED_UNSUPPORTED = 0;
057: /**
058: * See PDF Reference 1.4 Table 3.13.
059: */
060: public static final int VERSION1_40_BIT_ALGORITHM = 1;
061: /**
062: * See PDF Reference 1.4 Table 3.13.
063: */
064: public static final int VERSION2_VARIABLE_LENGTH_ALGORITHM = 2;
065: /**
066: * See PDF Reference 1.4 Table 3.13.
067: */
068: public static final int VERSION3_UNPUBLISHED_ALGORITHM = 3;
069: /**
070: * See PDF Reference 1.4 Table 3.13.
071: */
072: public static final int VERSION4_SECURITY_HANDLER = 4;
073:
074: /**
075: * The default security handler.
076: */
077: public static final String DEFAULT_NAME = "Standard";
078:
079: /**
080: * The default length for the encryption key.
081: */
082: public static final int DEFAULT_LENGTH = 40;
083:
084: /**
085: * The default version, according to the PDF Reference.
086: */
087: public static final int DEFAULT_VERSION = VERSION0_UNDOCUMENTED_UNSUPPORTED;
088:
089: /**
090: * COS encryption dictionary.
091: */
092: protected COSDictionary encryptionDictionary = null;
093:
094: /**
095: * creates a new empty encryption dictionary.
096: */
097: public PDEncryptionDictionary() {
098: encryptionDictionary = new COSDictionary();
099: }
100:
101: /**
102: * creates a new encryption dictionary from the low level dictionary provided.
103: * @param d the low level dictionary that will be managed by the newly created object
104: */
105: public PDEncryptionDictionary(COSDictionary d) {
106: encryptionDictionary = d;
107: }
108:
109: /**
110: * This will get the dictionary associated with this encryption dictionary.
111: *
112: * @return The COS dictionary that this object wraps.
113: */
114: public COSDictionary getCOSDictionary() {
115: return encryptionDictionary;
116: }
117:
118: /**
119: * Sets the filter entry of the encryption dictionary.
120: *
121: * @param filter The filter name.
122: */
123: public void setFilter(String filter) {
124: encryptionDictionary.setItem(COSName.FILTER, COSName
125: .getPDFName(filter));
126: }
127:
128: /**
129: * Get the name of the filter.
130: *
131: * @return The filter name contained in this encryption dictionary.
132: */
133: public String getFilter() {
134: return encryptionDictionary.getNameAsString(COSName.FILTER);
135: }
136:
137: /**
138: * Set the subfilter entry of the encryption dictionary.
139: *
140: * @param subfilter The value of the subfilter field.
141: */
142: public void setSubFilter(String subfilter) {
143: encryptionDictionary.setName("SubFilter", subfilter);
144: }
145:
146: /**
147: * This will set the V entry of the encryption dictionary.<br /><br />
148: * See PDF Reference 1.4 Table 3.13. <br /><br/>
149: * <b>Note: This value is used to decrypt the pdf document. If you change this when
150: * the document is encrypted then decryption will fail!.</b>
151: *
152: * @param version The new encryption version.
153: */
154: public void setVersion(int version) {
155: encryptionDictionary.setInt("V", version);
156: }
157:
158: /**
159: * This will return the V entry of the encryption dictionary.<br /><br />
160: * See PDF Reference 1.4 Table 3.13.
161: *
162: * @return The encryption version to use.
163: */
164: public int getVersion() {
165: return encryptionDictionary.getInt("V", 0);
166: }
167:
168: /**
169: * This will set the number of bits to use for the encryption algorithm.
170: *
171: * @param length The new key length.
172: */
173: public void setLength(int length) {
174: encryptionDictionary.setInt("Length", length);
175: }
176:
177: /**
178: * This will return the Length entry of the encryption dictionary.<br /><br />
179: * The length in <b>bits</b> for the encryption algorithm. This will return a multiple of 8.
180: *
181: * @return The length in bits for the encryption algorithm
182: */
183: public int getLength() {
184: return encryptionDictionary.getInt("Length", 40);
185: }
186:
187: /**
188: * This will set the R entry of the encryption dictionary.<br /><br />
189: * See PDF Reference 1.4 Table 3.14. <br /><br/>
190: *
191: * <b>Note: This value is used to decrypt the pdf document. If you change this when
192: * the document is encrypted then decryption will fail!.</b>
193: *
194: * @param revision The new encryption version.
195: */
196: public void setRevision(int revision) {
197: encryptionDictionary.setInt("R", revision);
198: }
199:
200: /**
201: * This will return the R entry of the encryption dictionary.<br /><br />
202: * See PDF Reference 1.4 Table 3.14.
203: *
204: * @return The encryption revision to use.
205: */
206: public int getRevision() {
207: return encryptionDictionary.getInt("R", DEFAULT_VERSION);
208: }
209:
210: /**
211: * This will set the O entry in the standard encryption dictionary.
212: *
213: * @param o A 32 byte array or null if there is no owner key.
214: *
215: * @throws IOException If there is an error setting the data.
216: */
217: public void setOwnerKey(byte[] o) throws IOException {
218: COSString owner = new COSString();
219: owner.append(o);
220: encryptionDictionary.setItem(COSName.getPDFName("O"), owner);
221: }
222:
223: /**
224: * This will get the O entry in the standard encryption dictionary.
225: *
226: * @return A 32 byte array or null if there is no owner key.
227: *
228: * @throws IOException If there is an error accessing the data.
229: */
230: public byte[] getOwnerKey() throws IOException {
231: byte[] o = null;
232: COSString owner = (COSString) encryptionDictionary
233: .getDictionaryObject(COSName.getPDFName("O"));
234: if (owner != null) {
235: o = owner.getBytes();
236: }
237: return o;
238: }
239:
240: /**
241: * This will set the U entry in the standard encryption dictionary.
242: *
243: * @param u A 32 byte array.
244: *
245: * @throws IOException If there is an error setting the data.
246: */
247: public void setUserKey(byte[] u) throws IOException {
248: COSString user = new COSString();
249: user.append(u);
250: encryptionDictionary.setItem(COSName.getPDFName("U"), user);
251: }
252:
253: /**
254: * This will get the U entry in the standard encryption dictionary.
255: *
256: * @return A 32 byte array or null if there is no user key.
257: *
258: * @throws IOException If there is an error accessing the data.
259: */
260: public byte[] getUserKey() throws IOException {
261: byte[] u = null;
262: COSString user = (COSString) encryptionDictionary
263: .getDictionaryObject(COSName.getPDFName("U"));
264: if (user != null) {
265: u = user.getBytes();
266: }
267: return u;
268: }
269:
270: /**
271: * This will set the permissions bit mask.
272: *
273: * @param permissions The new permissions bit mask
274: */
275: public void setPermissions(int permissions) {
276: encryptionDictionary.setInt("P", permissions);
277: }
278:
279: /**
280: * This will get the permissions bit mask.
281: *
282: * @return The permissions bit mask.
283: */
284: public int getPermissions() {
285: return encryptionDictionary.getInt("P", 0);
286: }
287:
288: /**
289: * This will set the Recipients field of the dictionary. This field contains an array
290: * of string.
291: * @param recipients the array of bytes arrays to put in the Recipients field.
292: * @throws IOException If there is an error setting the data.
293: */
294: public void setRecipients(byte[][] recipients) throws IOException {
295: COSArray array = new COSArray();
296: for (int i = 0; i < recipients.length; i++) {
297: COSString recip = new COSString();
298: recip.append(recipients[i]);
299: recip.setForceLiteralForm(true);
300: array.add(recip);
301: }
302: encryptionDictionary.setItem(COSName.getPDFName("Recipients"),
303: array);
304: }
305:
306: /**
307: * Returns the number of recipients contained in the Recipients field of the dictionary.
308: *
309: * @return the number of recipients contained in the Recipients field.
310: */
311: public int getRecipientsLength() {
312: COSArray array = (COSArray) encryptionDictionary
313: .getItem(COSName.getPDFName("Recipients"));
314: return array.size();
315: }
316:
317: /**
318: * returns the COSString contained in the Recipients field at position i.
319: *
320: * @param i the position in the Recipients field array.
321: *
322: * @return a COSString object containing information about the recipient number i.
323: */
324: public COSString getRecipientStringAt(int i) {
325: COSArray array = (COSArray) encryptionDictionary
326: .getItem(COSName.getPDFName("Recipients"));
327: return (COSString) array.get(i);
328: }
329: }
|