1 | /* | |
2 | * $Id: OutputStreamEncryption.java 3117 2008-01-31 05:53:22Z xlv $ | |
3 | * | |
4 | * Copyright 2006 Paulo Soares | |
5 | * | |
6 | * The contents of this file are subject to the Mozilla Public License Version 1.1 | |
7 | * (the "License"); you may not use this file except in compliance with the License. | |
8 | * You may obtain a copy of the License at http://www.mozilla.org/MPL/ | |
9 | * | |
10 | * Software distributed under the License is distributed on an "AS IS" basis, | |
11 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License | |
12 | * for the specific language governing rights and limitations under the License. | |
13 | * | |
14 | * The Original Code is 'iText, a free JAVA-PDF library'. | |
15 | * | |
16 | * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by | |
17 | * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. | |
18 | * All Rights Reserved. | |
19 | * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer | |
20 | * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. | |
21 | * | |
22 | * Contributor(s): all the names of the contributors are added in the source code | |
23 | * where applicable. | |
24 | * | |
25 | * Alternatively, the contents of this file may be used under the terms of the | |
26 | * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the | |
27 | * provisions of LGPL are applicable instead of those above. If you wish to | |
28 | * allow use of your version of this file only under the terms of the LGPL | |
29 | * License and not to allow others to use your version of this file under | |
30 | * the MPL, indicate your decision by deleting the provisions above and | |
31 | * replace them with the notice and other provisions required by the LGPL. | |
32 | * If you do not delete the provisions above, a recipient may use your version | |
33 | * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. | |
34 | * | |
35 | * This library is free software; you can redistribute it and/or modify it | |
36 | * under the terms of the MPL as stated above or under the terms of the GNU | |
37 | * Library General Public License as published by the Free Software Foundation; | |
38 | * either version 2 of the License, or any later version. | |
39 | * | |
40 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
41 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | |
42 | * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more | |
43 | * details. | |
44 | * | |
45 | * If you didn't download this code from the following link, you should check if | |
46 | * you aren't using an obsolete version: | |
47 | * http://www.lowagie.com/iText/ | |
48 | */ | |
49 | package com.lowagie.text.pdf; | |
50 | ||
51 | import com.lowagie.text.ExceptionConverter; | |
52 | import com.lowagie.text.pdf.crypto.AESCipher; | |
53 | import com.lowagie.text.pdf.crypto.IVGenerator; | |
54 | import com.lowagie.text.pdf.crypto.ARCFOUREncryption; | |
55 | import java.io.IOException; | |
56 | import java.io.OutputStream; | |
57 | ||
58 | public class OutputStreamEncryption extends OutputStream { | |
59 | | |
60 | protected OutputStream out; | |
61 | protected ARCFOUREncryption arcfour; | |
62 | protected AESCipher cipher; | |
63 | private byte[] sb = new byte[1]; | |
64 | private static final int AES_128 = 4; | |
65 | private boolean aes; | |
66 | private boolean finished; | |
67 | | |
68 | /** Creates a new instance of OutputStreamCounter */ | |
69 | public OutputStreamEncryption(OutputStream out, byte[] key, int off, int len, int revision) { | |
70 | try { | |
71 | this.out = out; | |
72 |
1
1. |
aes = revision == AES_128; |
73 |
1
1. |
if (aes) { |
74 | byte[] iv = IVGenerator.getIV(); | |
75 | byte[] nkey = new byte[len]; | |
76 |
1
1. |
System.arraycopy(key, off, nkey, 0, len); |
77 | cipher = new AESCipher(true, nkey, iv); | |
78 |
1
1. |
write(iv); |
79 | } | |
80 | else { | |
81 | arcfour = new ARCFOUREncryption(); | |
82 |
1
1. |
arcfour.prepareARCFOURKey(key, off, len); |
83 | } | |
84 | } catch (Exception ex) { | |
85 | throw new ExceptionConverter(ex); | |
86 | } | |
87 | } | |
88 | | |
89 | public OutputStreamEncryption(OutputStream out, byte[] key, int revision) { | |
90 | this(out, key, 0, key.length, revision); | |
91 | } | |
92 | | |
93 | /** Closes this output stream and releases any system resources | |
94 | * associated with this stream. The general contract of <code>close</code> | |
95 | * is that it closes the output stream. A closed stream cannot perform | |
96 | * output operations and cannot be reopened. | |
97 | * <p> | |
98 | * The <code>close</code> method of <code>OutputStream</code> does nothing. | |
99 | * | |
100 | * @exception IOException if an I/O error occurs. | |
101 | * | |
102 | */ | |
103 | public void close() throws IOException { | |
104 |
1
1. close : removed call to com/lowagie/text/pdf/OutputStreamEncryption::finish → NO_COVERAGE |
finish(); |
105 |
1
1. close : removed call to java/io/OutputStream::close → NO_COVERAGE |
out.close(); |
106 | } | |
107 | | |
108 | /** Flushes this output stream and forces any buffered output bytes | |
109 | * to be written out. The general contract of <code>flush</code> is | |
110 | * that calling it is an indication that, if any bytes previously | |
111 | * written have been buffered by the implementation of the output | |
112 | * stream, such bytes should immediately be written to their | |
113 | * intended destination. | |
114 | * <p> | |
115 | * The <code>flush</code> method of <code>OutputStream</code> does nothing. | |
116 | * | |
117 | * @exception IOException if an I/O error occurs. | |
118 | * | |
119 | */ | |
120 | public void flush() throws IOException { | |
121 | out.flush(); | |
122 | } | |
123 | | |
124 | /** Writes <code>b.length</code> bytes from the specified byte array | |
125 | * to this output stream. The general contract for <code>write(b)</code> | |
126 | * is that it should have exactly the same effect as the call | |
127 | * <code>write(b, 0, b.length)</code>. | |
128 | * | |
129 | * @param b the data. | |
130 | * @exception IOException if an I/O error occurs. | |
131 | * @see java.io.OutputStream#write(byte[], int, int) | |
132 | * | |
133 | */ | |
134 | public void write(byte[] b) throws IOException { | |
135 |
1
1. write : removed call to com/lowagie/text/pdf/OutputStreamEncryption::write → NO_COVERAGE |
write(b, 0, b.length); |
136 | } | |
137 | | |
138 | /** Writes the specified byte to this output stream. The general | |
139 | * contract for <code>write</code> is that one byte is written | |
140 | * to the output stream. The byte to be written is the eight | |
141 | * low-order bits of the argument <code>b</code>. The 24 | |
142 | * high-order bits of <code>b</code> are ignored. | |
143 | * <p> | |
144 | * Subclasses of <code>OutputStream</code> must provide an | |
145 | * implementation for this method. | |
146 | * | |
147 | * @param b the <code>byte</code>. | |
148 | * @exception IOException if an I/O error occurs. In particular, | |
149 | * an <code>IOException</code> may be thrown if the | |
150 | * output stream has been closed. | |
151 | * | |
152 | */ | |
153 | public void write(int b) throws IOException { | |
154 | sb[0] = (byte)b; | |
155 |
1
1. write : removed call to com/lowagie/text/pdf/OutputStreamEncryption::write → NO_COVERAGE |
write(sb, 0, 1); |
156 | } | |
157 | | |
158 | /** Writes <code>len</code> bytes from the specified byte array | |
159 | * starting at offset <code>off</code> to this output stream. | |
160 | * The general contract for <code>write(b, off, len)</code> is that | |
161 | * some of the bytes in the array <code>b</code> are written to the | |
162 | * output stream in order; element <code>b[off]</code> is the first | |
163 | * byte written and <code>b[off+len-1]</code> is the last byte written | |
164 | * by this operation. | |
165 | * <p> | |
166 | * The <code>write</code> method of <code>OutputStream</code> calls | |
167 | * the write method of one argument on each of the bytes to be | |
168 | * written out. Subclasses are encouraged to override this method and | |
169 | * provide a more efficient implementation. | |
170 | * <p> | |
171 | * If <code>b</code> is <code>null</code>, a | |
172 | * <code>NullPointerException</code> is thrown. | |
173 | * <p> | |
174 | * If <code>off</code> is negative, or <code>len</code> is negative, or | |
175 | * <code>off+len</code> is greater than the length of the array | |
176 | * <code>b</code>, then an <tt>IndexOutOfBoundsException</tt> is thrown. | |
177 | * | |
178 | * @param b the data. | |
179 | * @param off the start offset in the data. | |
180 | * @param len the number of bytes to write. | |
181 | * @exception IOException if an I/O error occurs. In particular, | |
182 | * an <code>IOException</code> is thrown if the output | |
183 | * stream is closed. | |
184 | * | |
185 | */ | |
186 | public void write(byte[] b, int off, int len) throws IOException { | |
187 |
1
1. write : negated conditional → NO_COVERAGE |
if (aes) { |
188 | byte[] b2 = cipher.update(b, off, len); | |
189 |
2
1. write : negated conditional → NO_COVERAGE 2. write : negated conditional → NO_COVERAGE |
if (b2 == null || b2.length == 0) |
190 | return; | |
191 |
1
1. write : removed call to java/io/OutputStream::write → NO_COVERAGE |
out.write(b2, 0, b2.length); |
192 | } | |
193 | else { | |
194 | byte[] b2 = new byte[Math.min(len, 4192)]; | |
195 |
2
1. write : changed conditional boundary → NO_COVERAGE 2. write : negated conditional → NO_COVERAGE |
while (len > 0) { |
196 | int sz = Math.min(len, b2.length); | |
197 |
1
1. write : removed call to com/lowagie/text/pdf/crypto/ARCFOUREncryption::encryptARCFOUR → NO_COVERAGE |
arcfour.encryptARCFOUR(b, off, sz, b2, 0); |
198 |
1
1. write : removed call to java/io/OutputStream::write → NO_COVERAGE |
out.write(b2, 0, sz); |
199 |
1
1. write : Replaced integer subtraction with addition → NO_COVERAGE |
len -= sz; |
200 |
1
1. write : Replaced integer addition with subtraction → NO_COVERAGE |
off += sz; |
201 | } | |
202 | } | |
203 | } | |
204 | | |
205 | public void finish() throws IOException { | |
206 |
1
1. finish : negated conditional → NO_COVERAGE |
if (!finished) { |
207 | finished = true; | |
208 |
1
1. finish : negated conditional → NO_COVERAGE |
if (aes) { |
209 | byte[] b; | |
210 | try { | |
211 | b = cipher.doFinal(); | |
212 | } catch (Exception ex) { | |
213 | throw new ExceptionConverter(ex); | |
214 | } | |
215 |
1
1. finish : removed call to java/io/OutputStream::write → NO_COVERAGE |
out.write(b, 0, b.length); |
216 | } | |
217 | } | |
218 | } | |
219 | } | |
Mutations | ||
72 |
1.1 |
|
73 |
1.1 |
|
76 |
1.1 |
|
78 |
1.1 |
|
82 |
1.1 |
|
104 |
1.1 |
|
105 |
1.1 |
|
135 |
1.1 |
|
155 |
1.1 |
|
187 |
1.1 |
|
189 |
1.1 2.2 |
|
191 |
1.1 |
|
195 |
1.1 2.2 |
|
197 |
1.1 |
|
198 |
1.1 |
|
199 |
1.1 |
|
200 |
1.1 |
|
206 |
1.1 |
|
208 |
1.1 |
|
215 |
1.1 |