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/signedData/PssSignedDataDemo.java 21 12.02.25 17:58 Dbratko $
059 // $Revision: 21 $
060 //
061
062 package demo.cms.signedData;
063
064 import java.io.ByteArrayInputStream;
065 import java.io.ByteArrayOutputStream;
066 import java.io.IOException;
067 import java.io.InputStream;
068 import java.security.AlgorithmParameters;
069 import java.security.InvalidAlgorithmParameterException;
070 import java.security.MessageDigest;
071 import java.security.NoSuchAlgorithmException;
072 import java.security.PrivateKey;
073 import java.security.SignatureException;
074 import java.security.cert.Certificate;
075 import java.security.spec.InvalidParameterSpecException;
076
077 import demo.DemoUtil;
078 import demo.keystore.CMSKeyStore;
079 import iaik.asn1.ObjectID;
080 import iaik.asn1.structures.AlgorithmID;
081 import iaik.asn1.structures.Attribute;
082 import iaik.cms.CMSException;
083 import iaik.cms.IssuerAndSerialNumber;
084 import iaik.cms.SecurityProvider;
085 import iaik.cms.SignedData;
086 import iaik.cms.SignedDataStream;
087 import iaik.cms.SignerInfo;
088 import iaik.cms.SubjectKeyID;
089 import iaik.cms.attributes.CMSContentType;
090 import iaik.cms.attributes.SigningTime;
091 import iaik.pkcs.pkcs1.MGF1ParameterSpec;
092 import iaik.pkcs.pkcs1.MaskGenerationAlgorithm;
093 import iaik.pkcs.pkcs1.RSAPssParameterSpec;
094 import iaik.utils.Util;
095 import iaik.x509.X509Certificate;
096 import iaik.x509.X509ExtensionException;
097
098 /**
099 * This class demonstrates the CMS SignedData implementation for
100 * the RSA-PSS (PKCS#1v2.1) algorithm.
101 */
102 public class PssSignedDataDemo {
103
104 // certificate of user 1
105 X509Certificate user1;
106 // private key of user 1
107 PrivateKey user1_pk;
108 // certificate of user 2
109 X509Certificate user2;
110 // private key of user 2
111 PrivateKey user2_pk;
112
113 // a certificate chain containing the user certs + CA
114 Certificate[] certificates;
115 Certificate[] certs;
116 Certificate[] user1Certs;
117
118 // just for attribute certificate testing
119 PrivateKey issuer1_pk;
120
121 /**
122 * Setups the demo certificate chains.
123 *
124 * Keys and certificate are retrieved from the demo KeyStore.
125 *
126 * @throws IOException if an file read error occurs
127 */
128 public PssSignedDataDemo() throws IOException {
129
130 System.out.println();
131 System.out.println("**********************************************************************************");
132 System.out.println("* PssSignedDataDemo *");
133 System.out.println("* (shows the usage of the CMS SignedData type with the RSA PSS signature scheme) *");
134 System.out.println("**********************************************************************************");
135 System.out.println();
136
137 // add all certificates to the list
138 user1Certs = CMSKeyStore.getCertificateChain(CMSKeyStore.RSA, CMSKeyStore.SZ_2048_SIGN_1);
139 user1 = (X509Certificate)user1Certs[0];
140 user1_pk = CMSKeyStore.getPrivateKey(CMSKeyStore.RSA, CMSKeyStore.SZ_2048_SIGN_1);
141 user2 = CMSKeyStore.getCertificateChain(CMSKeyStore.RSA, CMSKeyStore.SZ_2048_SIGN_1)[0];
142 user2_pk = CMSKeyStore.getPrivateKey(CMSKeyStore.RSA, CMSKeyStore.SZ_2048_SIGN_1);
143
144 certs = user1Certs;
145 certificates = new Certificate[certs.length+1];
146 System.arraycopy(certs, 0, certificates, 0, certs.length);
147 certificates[certs.length] = user2;
148 }
149
150 /**
151 * Creates a CMS <code>SignedData</code> object.
152 * <p>
153 *
154 * @param message the message to be signed, as byte representation
155 * @param mode the transmission mode, either IMPLICIT or EXPLICIT
156 * @return the BER encoding of the <code>SignedData</code> object just created
157 * @throws CMSException if the <code>SignedData</code> object cannot
158 * be created
159 * @throws IOException if some stream I/O error occurs
160 */
161 public byte[] createSignedDataStream(byte[] message, int mode) throws CMSException, IOException {
162
163 System.out.print("Create a new message signed by user 1 :");
164
165 // we are testing the stream interface
166 ByteArrayInputStream is = new ByteArrayInputStream(message);
167 // create a new SignedData object which includes the data
168 SignedDataStream signed_data = new SignedDataStream(is, mode);
169
170 // SignedData shall include the certificate chain for verifying
171 signed_data.setCertificates(certificates);
172
173 // cert at index 0 is the user certificate
174 IssuerAndSerialNumber issuer = new IssuerAndSerialNumber(user1);
175
176 // create a new SignerInfo for RSA-PSS with default parameters
177 SignerInfo signer_info = new SignerInfo(issuer,
178 (AlgorithmID)AlgorithmID.sha256.clone(),
179 (AlgorithmID)AlgorithmID.rsassaPss.clone(),
180 user1_pk);
181 // create some signed attributes
182 // the message digest attribute is automatically added
183 Attribute[] attributes = new Attribute[2];
184 try {
185 // content type is data
186 CMSContentType contentType = new CMSContentType(ObjectID.cms_data);
187 attributes[0] = new Attribute(contentType);
188 // signing time is now
189 SigningTime signingTime = new SigningTime();
190 attributes[1] = new Attribute(signingTime);
191 } catch (Exception ex) {
192 throw new CMSException("Error creating attribute: " + ex.toString());
193 }
194
195 // set the attributes
196 signer_info.setSignedAttributes(attributes);
197 // finish the creation of SignerInfo by calling method addSigner
198 try {
199 signed_data.addSignerInfo(signer_info);
200 // another SignerInfo without signed attributes and RSA-PSS with user defined parameters
201 AlgorithmID hashID = (AlgorithmID)AlgorithmID.sha256.clone();
202 AlgorithmID mgfID = (AlgorithmID)AlgorithmID.mgf1.clone();
203 int saltLength = 32;
204 AlgorithmID rsaPssID = null;
205 try {
206 rsaPssID = createPssAlgorithmID(hashID, mgfID, saltLength);
207 } catch (Exception ex) {
208 throw new CMSException("Error creating PSS parameters: " + ex.toString());
209 }
210 signer_info = new SignerInfo(new SubjectKeyID(user2),
211 hashID,
212 rsaPssID,
213 user2_pk);
214
215 // the message digest itself is protected
216 signed_data.addSignerInfo(signer_info);
217
218 } catch (NoSuchAlgorithmException ex) {
219 throw new CMSException("No implementation for signature algorithm: "+ex.getMessage());
220 } catch (X509ExtensionException ex) {
221 throw new CMSException("Cannot create SubjectKeyID for user2 : " + ex.getMessage());
222 }
223
224 // write the data through SignedData to any out-of-band place
225 if (mode == SignedDataStream.EXPLICIT) {
226 InputStream data_is = signed_data.getInputStream();
227 byte[] buf = new byte[1024];
228 int r;
229 while ((r = data_is.read(buf)) > 0) {
230 ; // skip data
231 }
232 }
233
234 // return the SignedData as DER encoded byte array with block size 2048
235 ByteArrayOutputStream os = new ByteArrayOutputStream();
236 signed_data.writeTo(os, 2048);
237 return os.toByteArray();
238 }
239
240
241 /**
242 * Parses a CMS <code>SignedData</code> object and verifies the signatures
243 * for all participated signers.
244 *
245 * @param signedData <code>SignedData</code> object as BER encoded byte array
246 * @param message the message which was transmitted out-of-band (if explicit signed),
247 * otherwise <code>null</code> (implicit signed)
248 *
249 * @return the inherent message as byte array
250 * @throws CMSException if any signature does not verify
251 * @throws IOException if some stream I/O error occurs
252 */
253 public byte[] getSignedDataStream(byte[] signedData, byte[] message) throws CMSException, IOException {
254
255 // we are testing the stream interface
256 ByteArrayInputStream is = new ByteArrayInputStream(signedData);
257 // create the SignedData object
258 SignedDataStream signed_data = new SignedDataStream(is);
259
260 if (signed_data.getMode() == SignedDataStream.EXPLICIT) {
261 // explicitly signed; set the data stream for digesting the message
262 signed_data.setInputStream(new ByteArrayInputStream(message));
263 }
264
265 // get an InputStream for reading the signed content
266 InputStream data = signed_data.getInputStream();
267 ByteArrayOutputStream os = new ByteArrayOutputStream();
268 Util.copyStream(data, os, null);
269
270 System.out.println("SignedData contains the following signer information:");
271 SignerInfo[] signer_infos = signed_data.getSignerInfos();
272
273 int numberOfSignerInfos = signer_infos.length;
274 if (numberOfSignerInfos == 0) {
275 String warning = "Warning: Unsigned message (no SignerInfo included)!";
276 System.err.println(warning);
277 throw new CMSException(warning);
278 } else {
279 for (int i = 0; i < numberOfSignerInfos; i++) {
280
281 try {
282 // verify the signed data using the SignerInfo at index i
283 X509Certificate signer_cert = signed_data.verify(i);
284 // if the signature is OK the certificate of the signer is returned
285 System.out.println("Signature OK from signer: "+signer_cert.getSubjectDN());
286 // get signed attributes
287 SigningTime signingTime = (SigningTime)signer_infos[i].getSignedAttributeValue(ObjectID.signingTime);
288 if (signingTime != null) {
289 System.out.println("This message has been signed at " + signingTime.get());
290 }
291 CMSContentType contentType = (CMSContentType)signer_infos[i].getSignedAttributeValue(ObjectID.contentType);
292 if (contentType != null) {
293 System.out.println("The content has CMS content type " + contentType.get().getName());
294 }
295 } catch (SignatureException ex) {
296 // if the signature is not OK a SignatureException is thrown
297 System.out.println("Signature ERROR from signer: "+signed_data.getCertificate(signer_infos[i].getSignerIdentifier()).getSubjectDN());
298 throw new CMSException(ex.toString());
299 }
300 }
301
302 // now check alternative signature verification
303 System.out.println("Now check the signature assuming that no certs have been included:");
304 try {
305 SignerInfo signer_info = signed_data.verify(user1);
306 // if the signature is OK the certificate of the signer is returned
307 System.out.println("Signature OK from signer: "+user1.getSubjectDN());
308
309 } catch (SignatureException ex) {
310 // if the signature is not OK a SignatureException is thrown
311 System.out.println("Signature ERROR from signer: "+user1.getSubjectDN());
312 throw new CMSException(ex.toString());
313 }
314
315
316 try {
317 SignerInfo signer_info = signed_data.verify(user2);
318 // if the signature is OK the certificate of the signer is returned
319 System.out.println("Signature OK from signer: "+signed_data.getCertificate(signer_info.getSignerIdentifier()).getSubjectDN());
320
321 } catch (SignatureException ex) {
322 // if the signature is not OK a SignatureException is thrown
323 System.out.println("Signature ERROR from signer: "+user2.getSubjectDN());
324 throw new CMSException(ex.toString());
325 }
326 // in practice we also would validate the signer certificate(s)
327 }
328
329 return os.toByteArray();
330 }
331
332
333
334 /**
335 * Creates a CMS <code>SignedData</code> object.
336 * <p>
337 *
338 * @param message the message to be signed, as byte representation
339 * @param mode the mode, either SignedData.IMPLICIT or SignedData.EXPLICIT
340 * @return the DER encoded <code>SignedData</code> object
341 * @throws CMSException if the <code>SignedData</code> object cannot
342 * be created
343 */
344 public byte[] createSignedData(byte[] message, int mode) throws CMSException {
345
346 System.out.println("Create a new message signed by user 1 :");
347
348 // create a new SignedData object which includes the data
349 SignedData signed_data = new SignedData(message, mode);
350
351 // SignedData shall include the certificate chain for verifying
352 signed_data.setCertificates(certificates);
353
354 // cert at index 0 is the user certificate
355 IssuerAndSerialNumber issuer = new IssuerAndSerialNumber(user1);
356
357 // create a new SignerInfo for RSA-PSS with default parameters
358 SignerInfo signer_info = new SignerInfo(issuer,
359 (AlgorithmID)AlgorithmID.sha256.clone(),
360 (AlgorithmID)AlgorithmID.rsassaPss.clone(),
361 user1_pk);
362
363 // create some signed attributes
364 // the message digest attribute is automatically added
365 Attribute[] attributes = new Attribute[2];
366 try {
367 // content type is data
368 CMSContentType contentType = new CMSContentType(ObjectID.cms_data);
369 attributes[0] = new Attribute(contentType);
370 // signing time is now
371 SigningTime signingTime = new SigningTime();
372 attributes[1] = new Attribute(signingTime);
373 } catch (Exception ex) {
374 throw new CMSException("Error creating attribute: " + ex.toString());
375 }
376
377 // set the attributes
378 signer_info.setSignedAttributes(attributes);
379 // finish the creation of SignerInfo by calling method addSigner
380 try {
381 signed_data.addSignerInfo(signer_info);
382
383 // another SignerInfo without signed attributes and RSA-PSS with user defined parameters
384 AlgorithmID hashID = (AlgorithmID)AlgorithmID.sha256.clone();
385 AlgorithmID mgfID = (AlgorithmID)AlgorithmID.mgf1.clone();
386 int saltLength = 32;
387 AlgorithmID rsaPssID = null;
388 try {
389 rsaPssID = createPssAlgorithmID(hashID, mgfID, saltLength);
390 } catch (Exception ex) {
391 throw new CMSException("Error creating PSS parameters: " + ex.toString());
392 }
393 signer_info = new SignerInfo(new SubjectKeyID(user2),
394 hashID,
395 rsaPssID,
396 user2_pk);
397
398 signed_data.addSignerInfo(signer_info);
399
400 } catch (NoSuchAlgorithmException ex) {
401 throw new CMSException("No implementation for signature algorithm: "+ex.getMessage());
402 } catch (X509ExtensionException ex) {
403 throw new CMSException("Cannot create SubjectKeyID for user2 : " + ex.getMessage());
404 }
405 return signed_data.getEncoded();
406 }
407
408
409 /**
410 * Parses a CMS <code>SignedData</code> object and verifies the signatures
411 * for all participated signers.
412 *
413 * @param encoding the DER encoded <code>SignedData</code> object
414 * @param message the message which was transmitted out-of-band (if explicit signed),
415 * otherwise <code>null</code> (implicit signed)
416 *
417 * @return the inherent message as byte array
418 * @throws CMSException if any signature does not verify
419 * @throws IOException if some stream I/O error occurs
420 */
421 public byte[] getSignedData(byte[] encoding, byte[] message) throws CMSException, IOException {
422
423 // create the SignedData object
424 SignedData signed_data = new SignedData(new ByteArrayInputStream(encoding));
425 if (signed_data.getMode() == SignedData.EXPLICIT) {
426 // explicitly signed; set the data stream for digesting the message
427 signed_data.setContent(message);
428 }
429
430 System.out.println("SignedData contains the following signer information:");
431 SignerInfo[] signer_infos = signed_data.getSignerInfos();
432
433 int numberOfSignerInfos = signer_infos.length;
434 if (numberOfSignerInfos == 0) {
435 String warning = "Warning: Unsigned message (no SignerInfo included)!";
436 System.err.println(warning);
437 throw new CMSException(warning);
438 } else {
439 for (int i = 0; i < numberOfSignerInfos; i++) {
440 try {
441 // verify the signed data using the SignerInfo at index i
442 X509Certificate signer_cert = signed_data.verify(i);
443 // if the signature is OK the certificate of the signer is returned
444 System.out.println("Signature OK from signer: "+signer_cert.getSubjectDN());
445 // get signed attributes
446 SigningTime signingTime = (SigningTime)signer_infos[i].getSignedAttributeValue(ObjectID.signingTime);
447 if (signingTime != null) {
448 System.out.println("This message has been signed at " + signingTime.get());
449 }
450 CMSContentType contentType = (CMSContentType)signer_infos[i].getSignedAttributeValue(ObjectID.contentType);
451 if (contentType != null) {
452 System.out.println("The content has CMS content type " + contentType.get().getName());
453 }
454 } catch (SignatureException ex) {
455 // if the signature is not OK a SignatureException is thrown
456 System.out.println("Signature ERROR from signer: "+signed_data.getCertificate(signer_infos[i].getSignerIdentifier()).getSubjectDN());
457 throw new CMSException(ex.toString());
458 }
459 }
460
461 // now check alternative signature verification
462 System.out.println("Now check the signature assuming that no certs have been included:");
463 try {
464 SignerInfo signer_info = signed_data.verify(user1);
465 // if the signature is OK the certificate of the signer is returned
466 System.out.println("Signature OK from signer: "+signed_data.getCertificate(signer_info.getSignerIdentifier()).getSubjectDN());
467
468 } catch (SignatureException ex) {
469 // if the signature is not OK a SignatureException is thrown
470 System.out.println("Signature ERROR from signer: "+user1.getSubjectDN());
471 throw new CMSException(ex.toString());
472 }
473 try {
474 SignerInfo signer_info = signed_data.verify(user2);
475 // if the signature is OK the certificate of the signer is returned
476 System.out.println("Signature OK from signer: "+signed_data.getCertificate(signer_info.getSignerIdentifier()).getSubjectDN());
477
478 } catch (SignatureException ex) {
479 // if the signature is not OK a SignatureException is thrown
480 System.out.println("Signature ERROR from signer: "+user2.getSubjectDN());
481 throw new CMSException(ex.toString());
482 }
483 // in practice we also would validate the signer certificate(s)
484 }
485 return signed_data.getContent();
486 }
487
488 /**
489 * Creates an RSA-PSS AlgorithmID with the supplied parameters (hash algorithm id,
490 * mask generation function, salt length).
491 *
492 * @param hashID the hash algorithm to be used
493 * @param mgfID the mask generation function to be used
494 * @param saltLength the salt length to be used
495 *
496 * @return the RSA-PSS algorithm id with the given parameters
497 *
498 * @throws InvalidAlgorithmParameterException if the parameters cannot be created/set
499 * @throws NoSuchAlgorithmException if there is no AlgorithmParameters implementation
500 * for RSA-PSS
501 */
502 public static AlgorithmID createPssAlgorithmID(AlgorithmID hashID, AlgorithmID mgfID, int saltLength)
503 throws InvalidAlgorithmParameterException, NoSuchAlgorithmException {
504
505 SecurityProvider provider = SecurityProvider.getSecurityProvider();
506 AlgorithmID rsaPssID = (AlgorithmID)AlgorithmID.rsassaPss.clone();
507 mgfID.setParameter(hashID.toASN1Object());
508 // create a RSAPssParameterSpec
509 RSAPssParameterSpec pssParamSpec = new RSAPssParameterSpec(hashID, mgfID, saltLength);
510 // optionally set hash and mgf engines
511 MessageDigest hashEngine = provider.getMessageDigest(hashID);
512 pssParamSpec.setHashEngine(hashEngine);
513 MaskGenerationAlgorithm mgfEngine = provider.getMaskGenerationAlgorithm(mgfID);
514 MGF1ParameterSpec mgf1Spec = new MGF1ParameterSpec(hashID);
515 mgf1Spec.setHashEngine(hashEngine);
516 mgfEngine.setParameters(mgf1Spec);
517 pssParamSpec.setMGFEngine(mgfEngine);
518
519 AlgorithmParameters pssParams = null;
520 try {
521 pssParams = provider.getAlgorithmParameters(SecurityProvider.IMPLEMENTATION_NAME_RSA_PSS);
522 pssParams.init(pssParamSpec);
523 } catch (InvalidParameterSpecException ex) {
524 throw new InvalidAlgorithmParameterException("Cannot init PSS params: " + ex.getMessage());
525 }
526
527 rsaPssID.setAlgorithmParameters(pssParams);
528 return rsaPssID;
529 }
530
531 /**
532 * Tests the CMS SignedData implementation for
533 * the RSA-PSS (PKCS#1v2.1) algorithm.
534 */
535 public void start() {
536 // the test message
537 String m = "This is the test message.";
538 System.out.println("Test message: \""+m+"\"");
539 System.out.println();
540 byte[] message = m.getBytes();
541
542 try {
543 byte[] encoding;
544 byte[] received_message = null;
545 System.out.println("Stream implementation demos (RSA-PPS signing)");
546 System.out.println("=============================================");
547 //
548 // test CMS Implicit SignedDataStream
549 //
550 System.out.println("\nImplicit SignedDataStream demo [create]:\n");
551 encoding = createSignedDataStream(message, SignedDataStream.IMPLICIT);
552 // transmit data
553 System.out.println("\nImplicit SignedDataStream demo [parse]:\n");
554 received_message = getSignedDataStream(encoding, null);
555 System.out.print("\nSigned content: ");
556 System.out.println(new String(received_message));
557
558 //
559 // test CMS Explicit SignedDataStream
560 //
561 System.out.println("\nExplicit SignedDataStream demo [create]:\n");
562 encoding = createSignedDataStream(message, SignedDataStream.EXPLICIT);
563 // transmit data
564 System.out.println("\nExplicit SignedDataStream demo [parse]:\n");
565 received_message = getSignedDataStream(encoding, message);
566 System.out.print("\nSigned content: ");
567 System.out.println(new String(received_message));
568
569 // the non-stream implementation
570 System.out.println("\nNon-stream implementation demos (RSA-PPS signing)");
571 System.out.println("===================================================");
572
573 //
574 // test CMS Implicit SignedData
575 //
576 System.out.println("\nImplicit CMS SignedData demo [create]:\n");
577 encoding = createSignedData(message, SignedData.IMPLICIT);
578 // transmit data
579 System.out.println("\nImplicit CMS SignedData demo [parse]:\n");
580 received_message = getSignedData(encoding, null);
581 System.out.print("\nSigned content: ");
582 System.out.println(new String(received_message));
583
584 //
585 // test CMS Explicit SignedData
586 //
587 System.out.println("\nExplicit CMS SignedData demo [create]:\n");
588 encoding = createSignedData(message, SignedData.EXPLICIT);
589 // transmit data
590 System.out.println("\nExplicit CMS SignedData demo [parse]:\n");
591 received_message = getSignedData(encoding, message);
592 System.out.print("\nSigned content: ");
593 System.out.println(new String(received_message));
594
595 } catch (Exception ex) {
596 ex.printStackTrace();
597 throw new RuntimeException(ex.toString());
598 }
599 }
600
601 /**
602 * The main method.
603 */
604 public static void main(String argv[]) throws Exception {
605
606 DemoUtil.initDemos();
607 (new PssSignedDataDemo()).start();
608 System.out.println("\nReady!");
609 DemoUtil.waitKey();
610 }
611 }