source: josm/trunk/src/com/kitfox/svg/xml/cpx/CPXInputStream.java@ 6002

Last change on this file since 6002 was 6002, checked in by Don-vip, 11 years ago

fix #8742 - update svgsalamander to release 0.1.18+patch (fix bug SVGSALAMANDER-26) -> allow to open more SVG files

File size: 10.1 KB
Line 
1/*
2 * SVG Salamander
3 * Copyright (c) 2004, Mark McKay
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or
7 * without modification, are permitted provided that the following
8 * conditions are met:
9 *
10 * - Redistributions of source code must retain the above
11 * copyright notice, this list of conditions and the following
12 * disclaimer.
13 * - Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials
16 * provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
23 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
29 * OF THE POSSIBILITY OF SUCH DAMAGE.
30 *
31 * Mark McKay can be contacted at mark@kitfox.com. Salamander and other
32 * projects can be found at http://www.kitfox.com
33 *
34 * Created on February 12, 2004, 10:34 AM
35 */
36
37package com.kitfox.svg.xml.cpx;
38
39import com.kitfox.svg.SVGConst;
40import java.io.*;
41import java.util.*;
42import java.util.zip.*;
43import java.security.*;
44import java.util.logging.Level;
45import java.util.logging.Logger;
46import javax.crypto.*;
47
48/**
49 * This class reads/decodes the CPX file format. This format is a simple
50 * compression/encryption transformer for XML data. This stream takes in
51 * encrypted XML and outputs decrypted. It does this by checking for a magic
52 * number at the start of the stream. If absent, it treats the stream as
53 * raw XML data and passes it through unaltered. This is to aid development
54 * in debugging versions, where the XML files will not be in CPX format.
55 *
56 * See http://java.sun.com/developer/technicalArticles/Security/Crypto/
57 *
58 * @author Mark McKay
59 * @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
60 */
61public class CPXInputStream extends FilterInputStream implements CPXConsts {
62
63
64 SecureRandom sec = new SecureRandom();
65
66 Inflater inflater = new Inflater();
67
68 int xlateMode;
69
70 //Keep header bytes in case this stream turns out to be plain text
71 byte[] head = new byte[4];
72 int headSize = 0;
73 int headPtr = 0;
74
75 boolean reachedEOF = false;
76 byte[] inBuffer = new byte[2048];
77 byte[] decryptBuffer = new byte[2048];
78
79 /** Creates a new instance of CPXInputStream */
80 public CPXInputStream(InputStream in) throws IOException {
81 super(in);
82
83 //Determine processing type
84 for (int i = 0; i < 4; i++)
85 {
86 int val = in.read();
87 head[i] = (byte)val;
88 if (val == -1 || head[i] != MAGIC_NUMBER[i])
89 {
90 headSize = i + 1;
91 xlateMode = XL_PLAIN;
92 return;
93 }
94 }
95
96 xlateMode = XL_ZIP_CRYPT;
97 }
98
99 /**
100 * We do not allow marking
101 */
102 public boolean markSupported() { return false; }
103
104 /**
105 * Closes this input stream and releases any system resources
106 * associated with the stream.
107 * This
108 * method simply performs <code>in.close()</code>.
109 *
110 * @exception IOException if an I/O error occurs.
111 * @see java.io.FilterInputStream#in
112 */
113 public void close() throws IOException {
114 reachedEOF = true;
115 in.close();
116 }
117
118 /**
119 * Reads the next byte of data from this input stream. The value
120 * byte is returned as an <code>int</code> in the range
121 * <code>0</code> to <code>255</code>. If no byte is available
122 * because the end of the stream has been reached, the value
123 * <code>-1</code> is returned. This method blocks until input data
124 * is available, the end of the stream is detected, or an exception
125 * is thrown.
126 * <p>
127 * This method
128 * simply performs <code>in.read()</code> and returns the result.
129 *
130 * @return the next byte of data, or <code>-1</code> if the end of the
131 * stream is reached.
132 * @exception IOException if an I/O error occurs.
133 * @see java.io.FilterInputStream#in
134 */
135 public int read() throws IOException
136 {
137 final byte[] b = new byte[1];
138 int retVal = read(b, 0, 1);
139 if (retVal == -1) return -1;
140 return b[0];
141 }
142
143 /**
144 * Reads up to <code>byte.length</code> bytes of data from this
145 * input stream into an array of bytes. This method blocks until some
146 * input is available.
147 * <p>
148 * This method simply performs the call
149 * <code>read(b, 0, b.length)</code> and returns
150 * the result. It is important that it does
151 * <i>not</i> do <code>in.read(b)</code> instead;
152 * certain subclasses of <code>FilterInputStream</code>
153 * depend on the implementation strategy actually
154 * used.
155 *
156 * @param b the buffer into which the data is read.
157 * @return the total number of bytes read into the buffer, or
158 * <code>-1</code> if there is no more data because the end of
159 * the stream has been reached.
160 * @exception IOException if an I/O error occurs.
161 * @see java.io.FilterInputStream#read(byte[], int, int)
162 */
163 public int read(byte[] b) throws IOException
164 {
165 return read(b, 0, b.length);
166 }
167
168 /**
169 * Reads up to <code>len</code> bytes of data from this input stream
170 * into an array of bytes. This method blocks until some input is
171 * available.
172 * <p>
173 * This method simply performs <code>in.read(b, off, len)</code>
174 * and returns the result.
175 *
176 * @param b the buffer into which the data is read.
177 * @param off the start offset of the data.
178 * @param len the maximum number of bytes read.
179 * @return the total number of bytes read into the buffer, or
180 * <code>-1</code> if there is no more data because the end of
181 * the stream has been reached.
182 * @exception IOException if an I/O error occurs.
183 * @see java.io.FilterInputStream#in
184 */
185 public int read(byte[] b, int off, int len) throws IOException
186 {
187 if (reachedEOF) return -1;
188
189 if (xlateMode == XL_PLAIN)
190 {
191 int count = 0;
192 //Write header if appropriate
193 while (headPtr < headSize && len > 0)
194 {
195 b[off++] = head[headPtr++];
196 count++;
197 len--;
198 }
199
200 return (len == 0) ? count : count + in.read(b, off, len);
201 }
202
203 //Decrypt and inflate
204 if (inflater.needsInput() && !decryptChunk())
205 {
206 reachedEOF = true;
207
208 //Read remaining bytes
209 int numRead;
210 try {
211 numRead = inflater.inflate(b, off, len);
212 }
213 catch (Exception e)
214 {
215 Logger.getLogger(SVGConst.SVG_LOGGER).log(Level.WARNING, null, e);
216 return -1;
217 }
218
219 if (!inflater.finished())
220 {
221 Logger.getLogger(SVGConst.SVG_LOGGER).log(Level.WARNING,
222 "Inflation imncomplete");
223 }
224
225 return numRead == 0 ? -1 : numRead;
226 }
227
228 try
229 {
230 return inflater.inflate(b, off, len);
231 }
232 catch (DataFormatException e)
233 {
234 Logger.getLogger(SVGConst.SVG_LOGGER).log(Level.WARNING, null, e);
235 return -1;
236 }
237 }
238
239
240 /**
241 * Call when inflater indicates that it needs more bytes.
242 * @return - true if we decrypted more bytes to deflate, false if we
243 * encountered the end of stream
244 */
245 protected boolean decryptChunk() throws IOException
246 {
247 while (inflater.needsInput())
248 {
249 int numInBytes = in.read(inBuffer);
250 if (numInBytes == -1) return false;
251// int numDecryptBytes = cipher.update(inBuffer, 0, numInBytes, decryptBuffer);
252// inflater.setInput(decryptBuffer, 0, numDecryptBytes);
253inflater.setInput(inBuffer, 0, numInBytes);
254 }
255
256 return true;
257 }
258
259 /**
260 * This method returns 1 if we've not reached EOF, 0 if we have. Programs
261 * should not rely on this to determine the number of bytes that can be
262 * read without blocking.
263 */
264 public int available() { return reachedEOF ? 0 : 1; }
265
266 /**
267 * Skips bytes by reading them into a cached buffer
268 */
269 public long skip(long n) throws IOException
270 {
271 int skipSize = (int)n;
272 if (skipSize > inBuffer.length) skipSize = inBuffer.length;
273 return read(inBuffer, 0, skipSize);
274 }
275
276}
277
278/*
279 import java.security.KeyPairGenerator;
280 import java.security.KeyPair;
281 import java.security.KeyPairGenerator;
282 import java.security.PrivateKey;
283 import java.security.PublicKey;
284 import java.security.SecureRandom;
285 import java.security.Cipher;
286
287 ....
288
289 java.security.Security.addProvider(new cryptix.provider.Cryptix());
290
291 SecureRandom random = new SecureRandom(SecureRandom.getSeed(30));
292 KeyPairGenerator keygen = KeyPairGenerator.getInstance("RSA");
293 keygen.initialize(1024, random);
294 keypair = keygen.generateKeyPair();
295
296 PublicKey pubkey = keypair.getPublic();
297 PrivateKey privkey = keypair.getPrivate();
298 */
299
300/*
301 *
302 *Generate key pairs
303KeyPairGenerator keyGen =
304 KeyPairGenerator.getInstance("DSA");
305KeyGen.initialize(1024, new SecureRandom(userSeed));
306KeyPair pair = KeyGen.generateKeyPair();
307 */
Note: See TracBrowser for help on using the repository browser.