001/* 002 * $Id: OutputStreamEncryption.java 4784 2011-03-15 08:33:00Z blowagie $ 003 * 004 * This file is part of the iText (R) project. 005 * Copyright (c) 1998-2011 1T3XT BVBA 006 * Authors: Bruno Lowagie, Paulo Soares, et al. 007 * 008 * This program is free software; you can redistribute it and/or modify 009 * it under the terms of the GNU Affero General Public License version 3 010 * as published by the Free Software Foundation with the addition of the 011 * following permission added to Section 15 as permitted in Section 7(a): 012 * FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY 1T3XT, 013 * 1T3XT DISCLAIMS THE WARRANTY OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. 014 * 015 * This program is distributed in the hope that it will be useful, but 016 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 017 * or FITNESS FOR A PARTICULAR PURPOSE. 018 * See the GNU Affero General Public License for more details. 019 * You should have received a copy of the GNU Affero General Public License 020 * along with this program; if not, see http://www.gnu.org/licenses or write to 021 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 022 * Boston, MA, 02110-1301 USA, or download the license from the following URL: 023 * http://itextpdf.com/terms-of-use/ 024 * 025 * The interactive user interfaces in modified source and object code versions 026 * of this program must display Appropriate Legal Notices, as required under 027 * Section 5 of the GNU Affero General Public License. 028 * 029 * In accordance with Section 7(b) of the GNU Affero General Public License, 030 * a covered work must retain the producer line in every PDF that is created 031 * or manipulated using iText. 032 * 033 * You can be released from the requirements of the license by purchasing 034 * a commercial license. Buying such a license is mandatory as soon as you 035 * develop commercial activities involving the iText software without 036 * disclosing the source code of your own applications. 037 * These activities include: offering paid services to customers as an ASP, 038 * serving PDFs on the fly in a web application, shipping iText with a closed 039 * source product. 040 * 041 * For more information, please contact iText Software Corp. at this 042 * address: sales@itextpdf.com 043 */ 044package com.itextpdf.text.pdf; 045import com.itextpdf.text.ExceptionConverter; 046import com.itextpdf.text.pdf.crypto.AESCipher; 047import com.itextpdf.text.pdf.crypto.IVGenerator; 048import com.itextpdf.text.pdf.crypto.ARCFOUREncryption; 049import java.io.IOException; 050import java.io.OutputStream; 051 052public class OutputStreamEncryption extends OutputStream { 053 054 protected OutputStream out; 055 protected ARCFOUREncryption arcfour; 056 protected AESCipher cipher; 057 private byte[] sb = new byte[1]; 058 private static final int AES_128 = 4; 059 private static final int AES_256 = 5; 060 private boolean aes; 061 private boolean finished; 062 063 /** Creates a new instance of OutputStreamCounter */ 064 public OutputStreamEncryption(OutputStream out, byte key[], int off, int len, int revision) { 065 try { 066 this.out = out; 067 aes = (revision == AES_128 || revision == AES_256); 068 if (aes) { 069 byte[] iv = IVGenerator.getIV(); 070 byte[] nkey = new byte[len]; 071 System.arraycopy(key, off, nkey, 0, len); 072 cipher = new AESCipher(true, nkey, iv); 073 write(iv); 074 } 075 else { 076 arcfour = new ARCFOUREncryption(); 077 arcfour.prepareARCFOURKey(key, off, len); 078 } 079 } catch (Exception ex) { 080 throw new ExceptionConverter(ex); 081 } 082 } 083 084 public OutputStreamEncryption(OutputStream out, byte key[], int revision) { 085 this(out, key, 0, key.length, revision); 086 } 087 088 /** Closes this output stream and releases any system resources 089 * associated with this stream. The general contract of <code>close</code> 090 * is that it closes the output stream. A closed stream cannot perform 091 * output operations and cannot be reopened. 092 * <p> 093 * The <code>close</code> method of <code>OutputStream</code> does nothing. 094 * 095 * @exception IOException if an I/O error occurs. 096 * 097 */ 098 public void close() throws IOException { 099 finish(); 100 out.close(); 101 } 102 103 /** Flushes this output stream and forces any buffered output bytes 104 * to be written out. The general contract of <code>flush</code> is 105 * that calling it is an indication that, if any bytes previously 106 * written have been buffered by the implementation of the output 107 * stream, such bytes should immediately be written to their 108 * intended destination. 109 * <p> 110 * The <code>flush</code> method of <code>OutputStream</code> does nothing. 111 * 112 * @exception IOException if an I/O error occurs. 113 * 114 */ 115 public void flush() throws IOException { 116 out.flush(); 117 } 118 119 /** Writes <code>b.length</code> bytes from the specified byte array 120 * to this output stream. The general contract for <code>write(b)</code> 121 * is that it should have exactly the same effect as the call 122 * <code>write(b, 0, b.length)</code>. 123 * 124 * @param b the data. 125 * @exception IOException if an I/O error occurs. 126 * @see java.io.OutputStream#write(byte[], int, int) 127 * 128 */ 129 public void write(byte[] b) throws IOException { 130 write(b, 0, b.length); 131 } 132 133 /** Writes the specified byte to this output stream. The general 134 * contract for <code>write</code> is that one byte is written 135 * to the output stream. The byte to be written is the eight 136 * low-order bits of the argument <code>b</code>. The 24 137 * high-order bits of <code>b</code> are ignored. 138 * <p> 139 * Subclasses of <code>OutputStream</code> must provide an 140 * implementation for this method. 141 * 142 * @param b the <code>byte</code>. 143 * @exception IOException if an I/O error occurs. In particular, 144 * an <code>IOException</code> may be thrown if the 145 * output stream has been closed. 146 * 147 */ 148 public void write(int b) throws IOException { 149 sb[0] = (byte)b; 150 write(sb, 0, 1); 151 } 152 153 /** Writes <code>len</code> bytes from the specified byte array 154 * starting at offset <code>off</code> to this output stream. 155 * The general contract for <code>write(b, off, len)</code> is that 156 * some of the bytes in the array <code>b</code> are written to the 157 * output stream in order; element <code>b[off]</code> is the first 158 * byte written and <code>b[off+len-1]</code> is the last byte written 159 * by this operation. 160 * <p> 161 * The <code>write</code> method of <code>OutputStream</code> calls 162 * the write method of one argument on each of the bytes to be 163 * written out. Subclasses are encouraged to override this method and 164 * provide a more efficient implementation. 165 * <p> 166 * If <code>b</code> is <code>null</code>, a 167 * <code>NullPointerException</code> is thrown. 168 * <p> 169 * If <code>off</code> is negative, or <code>len</code> is negative, or 170 * <code>off+len</code> is greater than the length of the array 171 * <code>b</code>, then an <tt>IndexOutOfBoundsException</tt> is thrown. 172 * 173 * @param b the data. 174 * @param off the start offset in the data. 175 * @param len the number of bytes to write. 176 * @exception IOException if an I/O error occurs. In particular, 177 * an <code>IOException</code> is thrown if the output 178 * stream is closed. 179 * 180 */ 181 public void write(byte[] b, int off, int len) throws IOException { 182 if (aes) { 183 byte[] b2 = cipher.update(b, off, len); 184 if (b2 == null || b2.length == 0) 185 return; 186 out.write(b2, 0, b2.length); 187 } 188 else { 189 byte[] b2 = new byte[Math.min(len, 4192)]; 190 while (len > 0) { 191 int sz = Math.min(len, b2.length); 192 arcfour.encryptARCFOUR(b, off, sz, b2, 0); 193 out.write(b2, 0, sz); 194 len -= sz; 195 off += sz; 196 } 197 } 198 } 199 200 public void finish() throws IOException { 201 if (!finished) { 202 finished = true; 203 if (aes) { 204 byte[] b; 205 try { 206 b = cipher.doFinal(); 207 } catch (Exception ex) { 208 throw new ExceptionConverter(ex); 209 } 210 out.write(b, 0, b.length); 211 } 212 } 213 } 214}