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/pkcs7cms/PKCS7CMSEnvelopedDataDemo.java 22    12.02.25 17:58 Dbratko $
059    // $Revision: 22 $
060    //
061    
062    package demo.cms.pkcs7cms;
063    
064    import iaik.asn1.ASN1Object;
065    import iaik.asn1.structures.AlgorithmID;
066    import iaik.cms.CMSException;
067    import iaik.cms.EncryptedContentInfo;
068    import iaik.cms.EncryptedContentInfoStream;
069    import iaik.cms.EnvelopedData;
070    import iaik.cms.EnvelopedDataStream;
071    import iaik.cms.KeyTransRecipientInfo;
072    import iaik.cms.RecipientInfo;
073    import iaik.pkcs.PKCSException;
074    import iaik.security.random.SecRandom;
075    import iaik.utils.Util;
076    import iaik.x509.X509Certificate;
077    
078    import java.io.ByteArrayInputStream;
079    import java.io.ByteArrayOutputStream;
080    import java.io.IOException;
081    import java.io.InputStream;
082    import java.security.InvalidKeyException;
083    import java.security.NoSuchAlgorithmException;
084    import java.security.PrivateKey;
085    import java.security.SecureRandom;
086    
087    import demo.DemoUtil;
088    import demo.keystore.CMSKeyStore;
089    
090    
091    /**
092     * Compares the usage of the IAIK CMS EnvelopedData(Stream) implementation against the
093     * IAIK PKCS#7 EnvelopedData(Stream) implementation.
094     */
095    public class PKCS7CMSEnvelopedDataDemo {
096    
097      // certificate of user 1
098      X509Certificate user1;
099      // private key of user 1
100      PrivateKey user1_pk;
101      // certificate of user 2
102      X509Certificate user2;
103      // private key of user 2
104      PrivateKey user2_pk;
105      // secure random number generator
106      SecureRandom random;
107    
108      /**
109       * Setup the demo certificate chains.
110       *
111       * Keys and certificate are retrieved from the demo KeyStore.
112       *
113       * @throws IOException if an file read error occurs
114       */
115      public PKCS7CMSEnvelopedDataDemo() throws IOException {
116        
117        System.out.println();
118        System.out.println("***********************************************************************************************");
119        System.out.println("*                                 PKCS7CMSEnvelopedDataDemo                                   *");
120        System.out.println("* (tests the CMS EnvelopedData against the IAIK-JCE PKCS#7 EnvelopedData type implementation) *");
121        System.out.println("***********************************************************************************************");
122        System.out.println();
123        
124        // add all certificates to the list
125        X509Certificate[] certs = CMSKeyStore.getCertificateChain(CMSKeyStore.RSA, CMSKeyStore.SZ_2048_CRYPT_1);
126        user1 = certs[0];
127        user1_pk = CMSKeyStore.getPrivateKey(CMSKeyStore.RSA, CMSKeyStore.SZ_2048_CRYPT_1);
128        user2 = CMSKeyStore.getCertificateChain(CMSKeyStore.RSA, CMSKeyStore.SZ_2048_CRYPT_2)[0];
129        user2_pk = CMSKeyStore.getPrivateKey(CMSKeyStore.RSA, CMSKeyStore.SZ_2048_CRYPT_2);
130      
131        random = SecRandom.getDefault();
132    
133      }
134    
135    
136      /**
137       * Creates a CMS <code>EnvelopedDataStream</code> message.
138       * <p>
139       * The enveloped-data content type consists of encrypted content of any
140       * type and encrypted content-encryption keys for one or more recipients.
141       * The combination of encrypted content and encrypted content-encryption
142       * key for a recipient is a "digital envelope" for that recipient. Any type
143       * of content can be enveloped for any number of recipients in parallel.
144       *
145       * @param message the message to be enveloped, as byte representation
146       * @return the DER encoding of the <code>EnvelopedData</code> object just created
147       * @throws CMSException if the <code>EnvelopedData</code> object cannot
148       *                          be created
149       * @throws IOException if an I/O error occurs
150       */
151      public byte[] createEnvelopedDataStream(byte[] message) throws CMSException, IOException {
152    
153        EnvelopedDataStream enveloped_data;
154    
155        // we are testing the stream interface
156        ByteArrayInputStream is = new ByteArrayInputStream(message);
157        // create a new EnvelopedData object encrypted with AES
158        try {
159          enveloped_data = new EnvelopedDataStream(is, (AlgorithmID)AlgorithmID.aes256_CBC.clone());
160        } catch (NoSuchAlgorithmException ex) {
161          throw new CMSException(ex.toString());
162        }
163    
164    
165        // create the recipient infos
166        KeyTransRecipientInfo[] recipients = new KeyTransRecipientInfo[2];
167        // user1 is the first receiver
168        recipients[0] = new KeyTransRecipientInfo(user1, (AlgorithmID)AlgorithmID.rsaEncryption.clone());
169        // user2 is the second receiver
170        recipients[1] = new KeyTransRecipientInfo(user2, (AlgorithmID)AlgorithmID.rsaEncryption.clone());
171        // specify the recipients of the encrypted message
172        enveloped_data.setRecipientInfos(recipients);
173    
174        // return the EnvelopedDate as DER encoded byte array with block size 2048
175        ByteArrayOutputStream os = new ByteArrayOutputStream();
176        enveloped_data.writeTo(os, 2048);
177        return os.toByteArray();
178      }
179    
180      /**
181       * Decrypts the encrypted content of the given <code>EnvelopedData</code> object for the
182       * specified recipient and returns the decrypted (= original) message.
183       *
184       * @param encoding the <code>EnvelopedData</code> object as DER encoded byte array
185       * @param privateKey the private key to decrypt the message
186       * @param recipientInfoIndex the index into the <code>RecipientInfo</code> array
187       *                           to which the specified private key belongs
188       *
189       * @return the recovered message, as byte array
190       * @throws CMSException if the message cannot be recovered
191       * @throws IOException if an I/O error occurs
192       */
193      public byte[] getEnvelopedDataStream(byte[] encoding, PrivateKey privateKey, int recipientInfoIndex)
194        throws CMSException, IOException {
195    
196        // create the EnvelopedData object from a DER encoded byte array
197        // we are testing the stream interface
198        ByteArrayInputStream is = new ByteArrayInputStream(encoding);
199        EnvelopedDataStream enveloped_data = new EnvelopedDataStream(is);
200    
201        System.out.println("Information about the encrypted data:");
202        EncryptedContentInfoStream eci = (EncryptedContentInfoStream)enveloped_data.getEncryptedContentInfo();
203        System.out.println("Content type: "+eci.getContentType().getName());
204        System.out.println("Content encryption algorithm: "+eci.getContentEncryptionAlgorithm().getName());
205    
206        System.out.println("\nThis message can be decrypted by the owners of the following certificates:");
207        RecipientInfo[] recipients = enveloped_data.getRecipientInfos();
208        for (int i=0; i<recipients.length; i++) {
209          System.out.println("Recipient "+(i+1)+":");
210          System.out.println(recipients[i].getRecipientIdentifiers()[0]);
211        }
212    
213        // decrypt the message
214        try {
215          enveloped_data.setupCipher(privateKey, recipientInfoIndex);
216          InputStream decrypted = enveloped_data.getInputStream();
217          ByteArrayOutputStream os = new ByteArrayOutputStream();
218          Util.copyStream(decrypted, os, null);
219    
220          return os.toByteArray();
221    
222        } catch (InvalidKeyException ex) {
223          throw new CMSException("Private key error: "+ex.toString());
224        } catch (NoSuchAlgorithmException ex) {
225          throw new CMSException("Content encryption algorithm not implemented: "+ex.getMessage());
226        }
227      }
228    
229    
230      /**
231       * Creates a CMS <code>EnvelopedData</code> message.
232       * <p>
233       * The enveloped-data content type consists of encrypted content of any
234       * type and encrypted content-encryption keys for one or more recipients.
235       * The combination of encrypted content and encrypted content-encryption
236       * key for a recipient is a "digital envelope" for that recipient. Any type
237       * of content can be enveloped for any number of recipients in parallel.
238       *
239       * @param message the message to be enveloped, as byte representation
240       * @return the <code>EnvelopedData</code> as ASN.1 object
241       * @throws CMSException if the <code>EnvelopedData</code> object cannot
242       *                          be created
243       */
244      public ASN1Object createEnvelopedData(byte[] message) throws CMSException {
245    
246        EnvelopedData enveloped_data;
247    
248        // create a new EnvelopedData object encrypted with AES
249        try {
250          enveloped_data = new EnvelopedData(message, (AlgorithmID)AlgorithmID.aes256_CBC.clone());
251        } catch (NoSuchAlgorithmException ex) {
252          throw new CMSException(ex.toString());
253        }
254    
255      
256        // create the recipient infos
257        KeyTransRecipientInfo[] recipients = new KeyTransRecipientInfo[2];
258        // user1 is the first receiver
259        recipients[0] = new KeyTransRecipientInfo(user1, (AlgorithmID)AlgorithmID.rsaEncryption.clone());
260        // user2 is the second receiver
261        recipients[1] = new KeyTransRecipientInfo(user2, (AlgorithmID)AlgorithmID.rsaEncryption.clone());
262        // specify the recipients of the encrypted message
263        enveloped_data.setRecipientInfos(recipients);
264    
265        // return the EnvelopedDate as DER encoded byte array
266        return enveloped_data.toASN1Object();
267      }
268    
269    
270      /**
271       * Decrypts the encrypted content of the given <code>EnvelopedData</code> object for the
272       * specified recipient and returns the decrypted (= original) message.
273       *
274       * @param obj the <code>EnvelopedData</code> as ASN.1 object
275       * @param privateKey the private key to decrypt the message
276       * @param recipientInfoIndex the index into the <code>RecipientInfo</code> array
277       *                           to which the specified private key belongs
278       *
279       * @return the recovered message, as byte array
280       * @throws CMSException if the message cannot be recovered
281       */
282      public byte[] getEnvelopedData(ASN1Object obj, PrivateKey privateKey, int recipientInfoIndex) 
283        throws CMSException {
284    
285        EnvelopedData enveloped_data = new EnvelopedData(obj);
286    
287        System.out.println("Information about the encrypted data:");
288        EncryptedContentInfo eci = (EncryptedContentInfo)enveloped_data.getEncryptedContentInfo();
289        System.out.println("Content type: "+eci.getContentType().getName());
290        System.out.println("Content encryption algorithm: "+eci.getContentEncryptionAlgorithm().getName());
291    
292        System.out.println("\nThis message can be decrypted by the owners of the following certificates:");
293        RecipientInfo[] recipients = enveloped_data.getRecipientInfos();
294        for (int i=0; i<recipients.length; i++) {
295          System.out.println("Recipient "+(i+1)+":");
296          System.out.println(recipients[i].getRecipientIdentifiers()[0]);
297        }
298    
299        // decrypt the message
300        try {
301          enveloped_data.setupCipher(privateKey, recipientInfoIndex);
302          return enveloped_data.getContent();
303    
304        } catch (InvalidKeyException ex) {
305          throw new CMSException("Private key error: "+ex.toString());
306        } catch (NoSuchAlgorithmException ex) {
307          throw new CMSException("Content encryption algorithm not implemented: "+ex.getMessage());
308        }
309      }
310      
311      // PKCS#7
312      
313      /**
314       * Creates a PKCS#7 <code>EnvelopedDataStream</code> message.
315       * <p>
316       * The enveloped-data content type consists of encrypted content of any
317       * type and encrypted content-encryption keys for one or more recipients.
318       * The combination of encrypted content and encrypted content-encryption
319       * key for a recipient is a "digital envelope" for that recipient. Any type
320       * of content can be enveloped for any number of recipients in parallel.
321       *
322       * @param message the message to be enveloped, as byte representation
323       * @return the DER encoding of the <code>EnvelopedData</code> object just created
324       * @throws PKCSException if the <code>EnvelopedData</code> object cannot
325       *                          be created
326       * @throws IOException if an I/O error occurs
327       */
328      public byte[] createPKCS7EnvelopedDataStream(byte[] message) throws iaik.pkcs.PKCSException, IOException {
329    
330        iaik.pkcs.pkcs7.EnvelopedDataStream enveloped_data;
331    
332        // we are testing the stream interface
333        ByteArrayInputStream is = new ByteArrayInputStream(message);
334        // create a new EnvelopedData object encrypted with AES
335        try {
336          enveloped_data = new iaik.pkcs.pkcs7.EnvelopedDataStream(is, (AlgorithmID)AlgorithmID.aes256_CBC.clone());
337        } catch (NoSuchAlgorithmException ex) {
338          throw new iaik.pkcs.PKCSException(ex.toString());
339        }
340    
341        try {
342          // create the recipient infos
343          iaik.pkcs.pkcs7.RecipientInfo[] recipients = new iaik.pkcs.pkcs7.RecipientInfo[2];
344          // user1 is the first receiver
345          recipients[0] = new iaik.pkcs.pkcs7.RecipientInfo(user1, (AlgorithmID)AlgorithmID.rsaEncryption.clone());
346          // user2 is the second receiver
347          recipients[1] = new iaik.pkcs.pkcs7.RecipientInfo(user2, (AlgorithmID)AlgorithmID.rsaEncryption.clone());
348    
349          // specify the recipients of the encrypted message
350          enveloped_data.setRecipientInfos(recipients);
351        } catch (NoSuchAlgorithmException ex) {
352          throw new iaik.pkcs.PKCSException("Algorithm not supported: " + ex.toString());  
353        }
354    
355        // return the EnvelopedDate as DER encoded byte array with block size 2048
356        ByteArrayOutputStream os = new ByteArrayOutputStream();
357        enveloped_data.writeTo(os, 2048);
358        return os.toByteArray();
359      }
360    
361      /**
362       * Decrypts the encrypted content of the given <code>EnvelopedData</code> object for the
363       * specified recipient and returns the decrypted (= original) message.
364       *
365       * @param encoding the <code>EnvelopedData</code> object as DER encoded byte array
366       * @param privateKey the private key to decrypt the message
367       * @param recipientInfoIndex the index into the <code>RecipientInfo</code> array
368       *                           to which the specified private key belongs
369       *
370       * @return the recovered message, as byte array
371       * @throws PKCSException if the message cannot be recovered
372       * @throws IOException if an I/O error occurs
373       */
374      public byte[] getPKCS7EnvelopedDataStream(byte[] encoding, PrivateKey privateKey, int recipientInfoIndex) throws iaik.pkcs.PKCSException, IOException {
375    
376        // create the EnvelopedData object from a DER encoded byte array
377        // we are testing the stream interface
378        ByteArrayInputStream is = new ByteArrayInputStream(encoding);
379        iaik.pkcs.pkcs7.EnvelopedDataStream enveloped_data = new iaik.pkcs.pkcs7.EnvelopedDataStream(is);
380    
381        System.out.println("Information about the encrypted data:");
382        iaik.pkcs.pkcs7.EncryptedContentInfoStream eci = (iaik.pkcs.pkcs7.EncryptedContentInfoStream)enveloped_data.getEncryptedContentInfo();
383        System.out.println("Content type: "+eci.getContentType().getName());
384        System.out.println("Content encryption algorithm: "+eci.getContentEncryptionAlgorithm().getName());
385    
386        System.out.println("\nThis message can be decrypted by the owners of the following certificates:");
387        iaik.pkcs.pkcs7.RecipientInfo[] recipients = enveloped_data.getRecipientInfos();
388        for (int i=0; i<recipients.length; i++) {
389          System.out.println("Recipient "+(i+1)+":");
390          System.out.println(recipients[i].getIssuerAndSerialNumber());
391        }
392    
393    
394        // decrypt the message
395        try {
396          enveloped_data.setupCipher(privateKey, recipientInfoIndex);
397          InputStream decrypted = enveloped_data.getInputStream();
398          ByteArrayOutputStream os = new ByteArrayOutputStream();
399          Util.copyStream(decrypted, os, null);
400    
401          return os.toByteArray();
402    
403        } catch (InvalidKeyException ex) {
404          throw new iaik.pkcs.PKCSException("Private key error: "+ex.toString());
405        } catch (NoSuchAlgorithmException ex) {
406          throw new iaik.pkcs.PKCSException("Content encryption algorithm not implemented: "+ex.getMessage());
407        }
408      }
409    
410    
411      /**
412       * Creates a PKCS#7 <code>EnvelopedData</code> message.
413       * <p>
414       * The enveloped-data content type consists of encrypted content of any
415       * type and encrypted content-encryption keys for one or more recipients.
416       * The combination of encrypted content and encrypted content-encryption
417       * key for a recipient is a "digital envelope" for that recipient. Any type
418       * of content can be enveloped for any number of recipients in parallel.
419       *
420       * @param message the message to be enveloped, as byte representation
421       * @return the <code>EnvelopedData</code> as ASN.1 object
422       * @throws PKCSException if the <code>EnvelopedData</code> object cannot
423       *                          be created
424       * @throws IOException if an I/O error occurs
425       */
426      public ASN1Object createPKCS7EnvelopedData(byte[] message) throws iaik.pkcs.PKCSException, IOException {
427    
428        iaik.pkcs.pkcs7.EnvelopedData enveloped_data;
429    
430        // create a new EnvelopedData object encrypted with AES
431        try {
432          enveloped_data = new iaik.pkcs.pkcs7.EnvelopedData(message, (AlgorithmID)AlgorithmID.aes256_CBC.clone());
433        } catch (NoSuchAlgorithmException ex) {
434          throw new iaik.pkcs.PKCSException(ex.toString());
435        }
436    
437        try {
438          // create the recipient infos
439          iaik.pkcs.pkcs7.RecipientInfo[] recipients = new iaik.pkcs.pkcs7.RecipientInfo[2];
440          // user1 is the first receiver
441          recipients[0] = new iaik.pkcs.pkcs7.RecipientInfo(user1, (AlgorithmID)AlgorithmID.rsaEncryption.clone());
442          // user2 is the second receiver
443          recipients[1] = new iaik.pkcs.pkcs7.RecipientInfo(user2, (AlgorithmID)AlgorithmID.rsaEncryption.clone());
444    
445          // specify the recipients of the encrypted message
446          enveloped_data.setRecipientInfos(recipients);
447        } catch (NoSuchAlgorithmException ex) {
448          throw new iaik.pkcs.PKCSException("Algorithm not supported: " + ex.toString());
449        }
450    
451        // return the EnvelopedDate as DER encoded byte array
452        return enveloped_data.toASN1Object();
453      }
454    
455    
456      /**
457       * Decrypts the encrypted content of the given <code>EnvelopedData</code> object for the
458       * specified recipient and returns the decrypted (= original) message.
459       *
460       * @param obj the <code>EnvelopedData</code> as ASN.1 object
461       * @param privateKey the private key to decrypt the message
462       * @param recipientInfoIndex the index into the <code>RecipientInfo</code> array
463       *                           to which the specified private key belongs
464       *
465       * @return the recovered message, as byte array
466       * @throws PKCSException if the message cannot be recovered
467       * @throws IOException if an I/O error occurs
468       */
469      public byte[] getPKCS7EnvelopedData(ASN1Object obj, PrivateKey privateKey, int recipientInfoIndex) throws iaik.pkcs.PKCSException, IOException {
470    
471    
472        iaik.pkcs.pkcs7.EnvelopedData enveloped_data = new iaik.pkcs.pkcs7.EnvelopedData(obj);
473    
474        System.out.println("Information about the encrypted data:");
475        iaik.pkcs.pkcs7.EncryptedContentInfo eci = (iaik.pkcs.pkcs7.EncryptedContentInfo)enveloped_data.getEncryptedContentInfo();
476        System.out.println("Content type: "+eci.getContentType().getName());
477        System.out.println("Content encryption algorithm: "+eci.getContentEncryptionAlgorithm().getName());
478    
479        System.out.println("\nThis message can be decrypted by the owners of the following certificates:");
480        iaik.pkcs.pkcs7.RecipientInfo[] recipients = enveloped_data.getRecipientInfos();
481        for (int i=0; i<recipients.length; i++) {
482          System.out.println("Recipient "+(i+1)+":");
483          System.out.println(recipients[i].getIssuerAndSerialNumber());
484        }
485    
486        // decrypt the message
487        try {
488          enveloped_data.setupCipher(privateKey, recipientInfoIndex);
489          return enveloped_data.getContent();
490    
491        } catch (InvalidKeyException ex) {
492          throw new iaik.pkcs.PKCSException("Private key error: "+ex.toString());
493        } catch (NoSuchAlgorithmException ex) {
494          throw new iaik.pkcs.PKCSException("Content encryption algorithm not implemented: "+ex.getMessage());
495        }
496      }
497    
498    
499    
500      /**
501       * Starts the test.
502       */
503      public void start() {
504         // the test message
505        String m = "This is the test message.";
506        System.out.println("Test message: \""+m+"\"");
507        System.out.println();
508        byte[] message = m.getBytes();
509    
510        try {
511          byte[] data;
512          byte[] received_message = null;
513          System.out.println("Stream implementation demos");
514          System.out.println("===========================");
515    
516    
517          // the stream implementation
518          //
519          // test CMS EnvelopedDataStream
520          //
521          System.out.println("\nCMS EnvelopedDataStream demo [create]:\n");
522          data = createEnvelopedDataStream(message);
523          // transmit data
524          System.out.println("\nCMS EnvelopedDataStream demo [parse]:\n");
525          // user1 means index 0 (hardcoded for this demo)
526          received_message = getEnvelopedDataStream(data, user1_pk, 0);
527          System.out.print("\nDecrypted content: ");
528          System.out.println(new String(received_message));
529          
530          System.out.println("Testing compatibility to PKCS#7...");
531          
532          System.out.println("\nPKCS7 EnvelopedDataStream demo [create]:\n");
533          data = createPKCS7EnvelopedDataStream(message);
534          // transmit data
535          System.out.println("\nCMS EnvelopedDataStream demo [parse]:\n");
536          // user1 means index 0 (hardcoded for this demo)
537          received_message = getEnvelopedDataStream(data, user1_pk, 0);
538          System.out.print("\nDecrypted content: ");
539          System.out.println(new String(received_message));
540          
541          System.out.println("\nPKCS7 EnvelopedDataStream demo [create]:\n");
542          data = createPKCS7EnvelopedDataStream(message);
543          // transmit data
544          System.out.println("\nCMS EnvelopedDataStream demo [parse]:\n");
545          // user1 means index 0 (hardcoded for this demo)
546          received_message = getEnvelopedDataStream(data, user1_pk, 0);
547          System.out.print("\nDecrypted content: ");
548          System.out.println(new String(received_message));
549          
550          System.out.println("\nCMS EnvelopedDataStream demo [create]:\n");
551          data = createEnvelopedDataStream(message);
552          // transmit data
553          System.out.println("\nPKCS7 EnvelopedDataStream demo [parse]:\n");
554          // user1 means index 0 (hardcoded for this demo)
555          received_message = getPKCS7EnvelopedDataStream(data, user1_pk, 0);
556          System.out.print("\nDecrypted content: ");
557          System.out.println(new String(received_message));
558    
559    
560    
561    
562          // the non-stream implementation
563          System.out.println("\nNon-stream implementation demos");
564          System.out.println("===============================");
565    
566          ASN1Object obj = null;
567    
568          //
569          // test CMS EnvelopedData
570          //
571          obj = null;
572          System.out.println("\nCMS EnvelopedData demo [create]:\n");
573          obj = createEnvelopedData(message);
574          // transmit data
575          System.out.println("\nCMS EnvelopedData demo [parse]:\n");
576          // user1 means index 0 (hardcoded for this demo)
577          received_message = getEnvelopedData(obj, user1_pk, 0);
578          System.out.print("\nDecrypted content: ");
579          System.out.println(new String(received_message));
580          
581          System.out.println("Testing compatibility to PKCS#7...");
582          
583          obj = null;
584          System.out.println("\nPKCS7 EnvelopedData demo [create]:\n");
585          obj = createPKCS7EnvelopedData(message);
586          // transmit data
587          System.out.println("\nCMS EnvelopedData demo [parse]:\n");
588          // user1 means index 0 (hardcoded for this demo)
589          received_message = getEnvelopedData(obj, user1_pk, 0);
590          System.out.print("\nDecrypted content: ");
591          System.out.println(new String(received_message));
592          
593          obj = null;
594          System.out.println("\nCMS EnvelopedData demo [create]:\n");
595          obj = createPKCS7EnvelopedData(message);
596          // transmit data
597          System.out.println("\nPKCS7 EnvelopedData demo [parse]:\n");
598          // user1 means index 0 (hardcoded for this demo)
599          received_message = getPKCS7EnvelopedData(obj, user1_pk, 0);
600          System.out.print("\nDecrypted content: ");
601          System.out.println(new String(received_message));
602    
603    
604            } catch (Exception ex) {
605              ex.printStackTrace();
606              throw new RuntimeException(ex.toString());
607            }
608      }
609    
610      /**
611       * The main method.
612       *
613       * @throws IOException
614       *            if an I/O error occurs when reading required keys
615       *            and certificates from files
616       */
617      public static void main(String argv[]) throws Exception {
618    
619            DemoUtil.initDemos();
620    
621        (new PKCS7CMSEnvelopedDataDemo()).start();
622        System.out.println("\nReady!");
623        DemoUtil.waitKey();
624      }
625    }