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 }