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