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