001 // Copyright (C) 2002 IAIK
002 // https://jce.iaik.tugraz.at
003 //
004 // Copyright (C) 2003 - 2025 Stiftung Secure Information and
005 // Communication Technologies SIC
006 // https://sic.tech
007 //
008 // All rights reserved.
009 //
010 // Redistribution and use in source and binary forms, with or without
011 // modification, are permitted provided that the following conditions
012 // are met:
013 // 1. Redistributions of source code must retain the above copyright
014 // notice, this list of conditions and the following disclaimer.
015 // 2. Redistributions in binary form must reproduce the above copyright
016 // notice, this list of conditions and the following disclaimer in the
017 // documentation and/or other materials provided with the distribution.
018 //
019 // THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
020 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
021 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
022 // ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
023 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
024 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
025 // OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
026 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
027 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
028 // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
029 // SUCH DAMAGE.
030
031 // Copyright (C) 2002 IAIK
032 // https://sic.tech/
033 //
034 // Copyright (C) 2003 - 2025 Stiftung Secure Information and
035 // Communication Technologies SIC
036 // https://sic.tech/
037 //
038 // All rights reserved.
039 //
040 // This source is provided for inspection purposes and recompilation only,
041 // unless specified differently in a contract with IAIK. This source has to
042 // be kept in strict confidence and must not be disclosed to any third party
043 // under any circumstances. Redistribution in source and binary forms, with
044 // or without modification, are <not> permitted in any case!
045 //
046 // THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
047 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
048 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
049 // ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
050 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
051 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
052 // OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
053 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
054 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
055 // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
056 // SUCH DAMAGE.
057 //
058 // $Header: /IAIK-CMS/current/src/demo/cms/compressedData/CompressedDataOutputStreamDemo.java 10 12.02.25 17:58 Dbratko $
059 // $Revision: 10 $
060 //
061
062 package demo.cms.compressedData;
063
064 import iaik.asn1.structures.AlgorithmID;
065 import iaik.cms.CMSAlgorithmID;
066 import iaik.cms.CMSException;
067 import iaik.cms.CompressedDataOutputStream;
068 import iaik.cms.CompressedDataStream;
069 import iaik.cms.ContentInfoOutputStream;
070 import iaik.utils.CryptoUtils;
071 import iaik.utils.Util;
072
073 import java.io.ByteArrayInputStream;
074 import java.io.ByteArrayOutputStream;
075 import java.io.IOException;
076 import java.io.InputStream;
077 import java.security.NoSuchAlgorithmException;
078
079 import demo.DemoUtil;
080
081 /**
082 * Demonstrates the usage of class {@link iaik.cms.CompressedDataOutputStream} and
083 * {@link iaik.cms.CompressedDataOutputStream} for compressing data using
084 * the CMS type CompressedData.
085 *
086 * @see iaik.cms.CompressedDataOutputStream
087 * @see iaik.cms.CompressedDataStream
088 */
089 public class CompressedDataOutputStreamDemo {
090
091 /**
092 * Default constructor.
093 */
094 public CompressedDataOutputStreamDemo() {
095 System.out.println();
096 System.out.println("**********************************************************************************");
097 System.out.println("* CompressedDataOutputStream demo *");
098 System.out.println("* (shows the usage of the CMS CompressedDataOutputStream type implementation) *");
099 System.out.println("**********************************************************************************");
100 System.out.println();
101 }
102
103
104 /**
105 * Uses the IAIK-CMS CompressedDataOutputStream class to create a CMS
106 * <code>CompressedData</code> object for compressing the given message.
107 * <p>
108 * @param message the message to be compressed, as byte representation
109 *
110 * @return the BER encoding of the <code>CompressedData</code> object just created
111 *
112 * @throws CMSException if the <code>CompressedData</code> object cannot
113 * be created
114 * @throws IOException if an I/O error occurs
115 */
116 public byte[] createCompressedData(byte[] message) throws CMSException, IOException {
117
118 System.out.println("Create a new CompressedData message.");
119
120 // the stream from which to read the data to be compressed
121 ByteArrayInputStream is = new ByteArrayInputStream(message);
122
123 // the stream to which to write the CompressedData
124 ByteArrayOutputStream resultStream = new ByteArrayOutputStream();
125
126 // wrap CompressedData into a ContentInfo
127 ContentInfoOutputStream contentInfoStream =
128 new ContentInfoOutputStream(CompressedDataStream.contentType, resultStream);
129 // create a new CompressedDataOutputStream
130 CompressedDataOutputStream compressedData =
131 new CompressedDataOutputStream(contentInfoStream,
132 (AlgorithmID)CMSAlgorithmID.zlib_compress.clone());
133
134 int blockSize = 8; // in real world we would use a block size like 2048
135 // write in the data to be compressed
136 byte[] buffer = new byte[blockSize];
137 int bytesRead;
138 while ((bytesRead = is.read(buffer)) != -1) {
139 compressedData.write(buffer, 0, bytesRead);
140 }
141
142 // closing the stream finishes encoding and closes the underlying stream
143 compressedData.close();
144 return resultStream.toByteArray();
145 }
146
147 /**
148 * Parses a CMS <code>CompressedData</code> object.
149 *
150 * @param encoding the <code>CompressedData</code> object as BER encoded byte array
151 *
152 * @return the decompressed message as byte array
153 *
154 * @throws CMSException if the CompressedData cannot be parsed
155 * @throws IOException if an I/O error occurs
156 * @throws NoSuchAlgorithmException if the compression algorithm is not supported
157 */
158 public byte[] getCompressedData(byte[] encoding)
159 throws CMSException, IOException, NoSuchAlgorithmException {
160
161 System.out.println("Parse CompressedData message.");
162 // we are testing the stream interface
163 ByteArrayInputStream is = new ByteArrayInputStream(encoding);
164 // create the CompressedData object
165 CompressedDataStream compressedData = new CompressedDataStream(is);
166
167 // get an InputStream for reading and decompressing the content
168 InputStream data = compressedData.getInputStream();
169 ByteArrayOutputStream os = new ByteArrayOutputStream();
170 Util.copyStream(data, os, null);
171
172 return os.toByteArray();
173 }
174
175
176 /**
177 * Starts the demo.
178 */
179 public void start() {
180 // the test message
181 String m = "ABABABABABABABBABABABABABABABBABABABABABABABBAABABABABABA.";
182 System.out.println("Test message: \""+m+"\"");
183 System.out.println();
184 byte[] message = m.getBytes();
185
186 try {
187 byte[] encoding;
188 byte[] receivedMessage = null;
189
190 System.out.println("\nCreating compressed message\n");
191 encoding = createCompressedData(message);
192 // transmit data
193 System.out.println("\nParsing compressed data\n");
194 receivedMessage = getCompressedData(encoding);
195 if (CryptoUtils.equalsBlock(message, receivedMessage) == false) {
196 throw new CMSException("Decompression error!");
197 }
198
199 System.out.print("\nContent: ");
200 System.out.println(new String(receivedMessage));
201
202 } catch (Exception ex) {
203 ex.printStackTrace();
204 throw new RuntimeException(ex.toString());
205 }
206 }
207
208 /**
209 * Main method.
210 */
211 public static void main(String argv[]) throws Exception {
212
213 DemoUtil.initDemos();
214
215 (new CompressedDataOutputStreamDemo()).start();
216 System.out.println("\nReady!");
217 DemoUtil.waitKey();
218 }
219 }