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/CompressedDataDemo.java 13 12.02.25 17:58 Dbratko $ 029// $Revision: 13 $ 030// 031 032package demo.cms.compressedData; 033 034import iaik.asn1.structures.AlgorithmID; 035import iaik.cms.CMSAlgorithmID; 036import iaik.cms.CMSException; 037import iaik.cms.CompressedData; 038import iaik.cms.CompressedDataStream; 039import iaik.cms.ContentInfo; 040import iaik.cms.ContentInfoStream; 041import iaik.cms.Utils; 042import iaik.utils.CryptoUtils; 043import iaik.utils.Util; 044 045import java.io.ByteArrayInputStream; 046import java.io.ByteArrayOutputStream; 047import java.io.IOException; 048import java.io.InputStream; 049import java.security.NoSuchAlgorithmException; 050 051import demo.DemoUtil; 052 053 054 055/** 056 * Demonstrates the usage of class {@link iaik.cms.CompressedDataStream} and 057 * {@link iaik.cms.CompressedData} for compressing/decompressing data using 058 * the CMS type CompressedData. 059 */ 060public class CompressedDataDemo { 061 062 /** 063 * In explcit mode the compressed content data has to be transmitted by other means. 064 */ 065 byte[] compressedContent_; 066 067 /** 068 * Default constructor. 069 */ 070 public CompressedDataDemo() { 071 System.out.println(); 072 System.out.println("**********************************************************************************"); 073 System.out.println("* CompressedDataDemo *"); 074 System.out.println("* (shows the usage of the CMS CompressedData type implementation) *"); 075 System.out.println("**********************************************************************************"); 076 System.out.println(); 077 } 078 079 080 /** 081 * Creates a CMS <code>CompressedData</code> object. 082 * <p> 083 * @param message the message to be compressed, as byte representation 084 * @param mode IMPLICIT (include compressed content) or 085 * EXPLICIT (do not include compressed content) 086 * 087 * @return the BER encoding of the <code>CompressedData</code> object just created 088 * 089 * @throws CMSException if the <code>CompressedData</code> object cannot 090 * be created 091 * @throws IOException if an I/O error occurs 092 * @throws NoSuchAlgorithmException if the compression algorithm is not supported 093 */ 094 public byte[] createCompressedDataStream(byte[] message, int mode) 095 throws CMSException, IOException, NoSuchAlgorithmException { 096 097 System.out.println("Create a new CompressedData message."); 098 099 // we are testing the stream interface 100 ByteArrayInputStream is = new ByteArrayInputStream(message); 101 102 // create a new CompressedData object 103 CompressedDataStream compressedData = new CompressedDataStream(is, 104 (AlgorithmID)CMSAlgorithmID.zlib_compress.clone(), 105 mode); 106 107 108 // in explicit mode transmit compressed content out-of-band 109 if (mode == CompressedDataStream.EXPLICIT) { 110 InputStream dataIs = compressedData.getInputStream(); 111 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 112 Utils.copyStream(dataIs, baos, null); 113 compressedContent_ = baos.toByteArray(); 114 } 115 116 // for testing return the CompressedData as BER encoded byte array with block size of 4 117 ByteArrayOutputStream os = new ByteArrayOutputStream(); 118 compressedData.setBlockSize(4); 119 ContentInfoStream cis = new ContentInfoStream(compressedData); 120 cis.writeTo(os); 121 return os.toByteArray(); 122 } 123 124 /** 125 * Parses a CMS <code>CompressedData</code> object. 126 * 127 * @param encoding the <code>CompressedData</code> object as BER encoded byte array 128 * @param compressedContent the compressed content which was transmitted out-of-band 129 * 130 * @return the decompressed message as byte array 131 * 132 * @throws CMSException if the CompressedData cannot be parsed 133 * @throws IOException if an I/O error occurs 134 * @throws NoSuchAlgorithmException if the compression algorithm is not supported 135 */ 136 public byte[] getCompressedDataStream(byte[] encoding, byte[] compressedContent) 137 throws CMSException, IOException, NoSuchAlgorithmException { 138 139 System.out.println("Parse CompressedData message."); 140 // we are testing the stream interface 141 ByteArrayInputStream is = new ByteArrayInputStream(encoding); 142 // create the CompressedData object 143 CompressedDataStream compressedData = new CompressedDataStream(is); 144 145 if (compressedData.getMode() == CompressedDataStream.EXPLICIT) { 146 // in explicit mode now provide the content received by other means 147 compressedData.setInputStream(new ByteArrayInputStream(compressedContent)); 148 } 149 150 // get an InputStream for reading and decompressing the content 151 InputStream data = compressedData.getInputStream(); 152 ByteArrayOutputStream os = new ByteArrayOutputStream(); 153 Util.copyStream(data, os, null); 154 155 return os.toByteArray(); 156 } 157 158 159 /** 160 * Creates a CMS <code>CompressedData</code> object. 161 * <p> 162 * 163 * @param message the message to be compressed, as byte representation 164 * @param mode IMPLICIT (include the compressed content) or 165 * EXPLICIT (do not include the compressed content) 166 * 167 * @return the DER encoded <code>CompressedData</code> 168 * 169 * @throws CMSException if the <code>CompressedData</code> object cannot 170 * be created 171 * @throws IOException if an I/O error occurs 172 * @throws NoSuchAlgorithmException if the compression algorithm is not supported 173 */ 174 public byte[] createCompressedData(byte[] message, int mode) 175 throws CMSException, IOException, NoSuchAlgorithmException { 176 177 System.out.println("Create a new CompressedData message."); 178 179 // create a new CompressedData object 180 CompressedData compressedData = new CompressedData(message, 181 (AlgorithmID)CMSAlgorithmID.zlib_compress.clone(), 182 mode); 183 // in explicit mode get the compressed content to transmit it by other means 184 if (mode == CompressedData.EXPLICIT) { 185 compressedContent_ = compressedData.getContent(); 186 } 187 ContentInfo ci = new ContentInfo(compressedData); 188 return ci.getEncoded(); 189 } 190 191 /** 192 * Parses a CMS <code>CompressedData</code> object. 193 * 194 * @param encoding the DER encoded <code>CompressedData</code> object 195 * @param compressedContent the compressed content which was transmitted out-of-band 196 * 197 * @return the decompressed message as byte array 198 * 199 * @throws CMSException if the CompressedData cannot be parsed 200 * @throws IOException if an I/O error occurs 201 * @throws NoSuchAlgorithmException if the compression algorithm is not supported 202 */ 203 public byte[] getCompressedData(byte[] encoding, byte[] compressedContent) 204 throws CMSException, IOException, NoSuchAlgorithmException { 205 206 System.out.println("Parse CompressedData message."); 207 ByteArrayInputStream encodedStream = new ByteArrayInputStream(encoding); 208 // create the CompressedData object 209 CompressedData compressedData = new CompressedData(encodedStream); 210 211 if (compressedData.getMode() == CompressedData.EXPLICIT) { 212 // in explicit mode provide the compressed content received by other means 213 compressedData.setContent(compressedContent); 214 } 215 // decompress 216 return compressedData.getContent(); 217 } 218 219 /** 220 * Starts the demo. 221 */ 222 public void start() { 223 // the test message 224 String m = "ABABABABABABABBABABABABABABABBABABABABABABABBAABABABABABA."; 225 System.out.println("Test message: \""+m+"\""); 226 System.out.println(); 227 byte[] message = m.getBytes(); 228 229 try { 230 byte[] encoding; 231 byte[] receivedMessage = null; 232 System.out.println("Stream implementation demos"); 233 System.out.println("==========================="); 234 235 // the stream implementation 236 237 // 238 // test CMS Implicit CompressedDataStream 239 // 240 System.out.println("\nImplicit CompressedDataStream demo [create]\n"); 241 encoding = createCompressedDataStream(message, CompressedDataStream.IMPLICIT); 242 // transmit data 243 System.out.println("\nImplicit CompressedDataStream demo [parse]\n"); 244 receivedMessage = getCompressedDataStream(encoding, null); 245 if (CryptoUtils.equalsBlock(message, receivedMessage) == false) { 246 throw new CMSException("Decompression error!"); 247 } 248 System.out.print("\nContent: "); 249 System.out.println(new String(receivedMessage)); 250 251 // 252 // test CMS Explicit CompressedDataStream 253 // 254 System.out.println("\nExplicit CompressedDataStream demo [create]\n"); 255 encoding = createCompressedDataStream(message, CompressedDataStream.EXPLICIT); 256 // transmit data 257 System.out.println("\nExplicit CompressedDataStream demo [parse]\n"); 258 receivedMessage = getCompressedDataStream(encoding, compressedContent_); 259 if (CryptoUtils.equalsBlock(message, receivedMessage) == false) { 260 throw new CMSException("Decompression error!"); 261 } 262 System.out.print("\nContent: "); 263 System.out.println(new String(receivedMessage)); 264 265 // the non-stream implementation 266 System.out.println("\nNon-stream implementation demos"); 267 System.out.println("==============================="); 268 269 // 270 // test CMS Implicit CompressedData 271 // 272 System.out.println("\nImplicit CompressedData demo [create]\n"); 273 encoding = createCompressedData(message, CompressedData.IMPLICIT); 274 // transmit data 275 System.out.println("\nImplicit CompressedData demo [parse]\n"); 276 receivedMessage = getCompressedData(encoding, null); 277 if (CryptoUtils.equalsBlock(message, receivedMessage) == false) { 278 throw new CMSException("Decompression error!"); 279 } 280 System.out.print("\nContent: "); 281 System.out.println(new String(receivedMessage)); 282 283 // 284 // test CMS Explicit CompressedData 285 // 286 System.out.println("\nExplicit CompressedData demo [create]\n"); 287 encoding = createCompressedData(message, CompressedData.EXPLICIT); 288 // transmit data 289 System.out.println("\nExplicit CompressedData demo [parse]\n"); 290 receivedMessage = getCompressedData(encoding, compressedContent_); 291 if (CryptoUtils.equalsBlock(message, receivedMessage) == false) { 292 throw new CMSException("Decompression error!"); 293 } 294 System.out.print("\nContent: "); 295 System.out.println(new String(receivedMessage)); 296 297 } catch (Exception ex) { 298 ex.printStackTrace(); 299 throw new RuntimeException(ex.toString()); 300 } 301 } 302 303 /** 304 * Main method. 305 */ 306 public static void main(String argv[]) throws Exception { 307 308 DemoUtil.initDemos(); 309 310 (new CompressedDataDemo()).start(); 311 System.out.println("\nReady!"); 312 DemoUtil.waitKey(); 313 } 314}