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.security.MessageDigest;
033:
034: import javax.crypto.Cipher;
035:
036: import de.intarsys.pdf.cos.COSObjectKey;
037:
038: /**
039: * An abstract superclass for the default implementation of
040: * {@link ICryptHandler}. The concrete implementations provide the standard RC4
041: * and AES algorithms.
042: *
043: */
044: abstract public class StandardCryptHandler extends AbstractCryptHandler {
045: /** The cipher object to be used in encrypting/decrypting */
046: protected Cipher cipher;
047:
048: /** The message digest used throughout the encryption/decryption */
049: protected MessageDigest md;
050:
051: /** A buffer for the bytes stemming from the generation number */
052: private byte[] generationBytes = new byte[2];
053:
054: /** A buffer for the bytes stemming from the object number */
055: private byte[] objectBytes = new byte[3];
056:
057: /**
058: * The key that was computed for the encryption instance.
059: */
060: private byte[] cryptKey;
061:
062: abstract protected byte[] basicDecrypt(byte[] data,
063: byte[] encryptionKey, int objectNum, int genNum)
064: throws COSSecurityException;
065:
066: abstract protected byte[] basicEncrypt(byte[] data,
067: byte[] encryptionKey, int objectNum, int genNum)
068: throws COSSecurityException;
069:
070: protected void updateHash(byte[] encryptionKey, int objectNum,
071: int genNum) {
072: md.reset();
073: md.update(encryptionKey);
074: objectBytes[0] = (byte) (objectNum & 0xff);
075: objectNum = objectNum >> 8;
076: objectBytes[1] = (byte) (objectNum & 0xff);
077: objectNum = objectNum >> 8;
078: objectBytes[2] = (byte) (objectNum & 0xff);
079: md.update(objectBytes);
080: generationBytes[0] = (byte) (genNum & 0xff);
081: genNum = genNum >> 8;
082: generationBytes[1] = (byte) (genNum & 0xff);
083: md.update(generationBytes);
084: }
085:
086: /*
087: * (non-Javadoc)
088: *
089: * @see de.intarsys.pdf.encryption.ISecurityHandler#decrypt(de.intarsys.pdf.cos.COSObjectKey,
090: * byte[])
091: */
092: public byte[] decrypt(COSObjectKey objectKey, byte[] bytes)
093: throws COSSecurityException {
094: if (bytes == null) {
095: return null;
096: }
097: if (objectKey == null) {
098: return bytes;
099: }
100: synchronized (this ) {
101: return basicDecrypt(bytes, getCryptKey(), objectKey
102: .getObjectNumber(), objectKey.getGenerationNumber());
103: }
104: }
105:
106: public StandardCryptHandler() {
107: super ();
108: }
109:
110: protected int length;
111:
112: public void init(byte[] pCryptKey) throws COSSecurityException {
113: cryptKey = pCryptKey;
114: length = cryptKey.length + 5;
115: if (length > 16) {
116: length = 16;
117: }
118: }
119:
120: /*
121: * (non-Javadoc)
122: *
123: * @see de.intarsys.pdf.encryption.ISecurityHandler#encrypt(de.intarsys.pdf.cos.COSObjectKey,
124: * byte[])
125: */
126: public byte[] encrypt(COSObjectKey objectKey, byte[] bytes)
127: throws COSSecurityException {
128: if (bytes == null) {
129: return null;
130: }
131: if (objectKey == null) {
132: return bytes;
133: }
134: synchronized (this ) {
135: return basicEncrypt(bytes, getCryptKey(), objectKey
136: .getObjectNumber(), objectKey.getGenerationNumber());
137: }
138: }
139:
140: protected byte[] getCryptKey() {
141: return cryptKey;
142: }
143: }
|