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/ecc/ECDSASignedDataDemo.java 36 12.02.25 17:58 Dbratko $
059 // $Revision: 36 $
060 //
061
062 package demo.cms.ecc;
063
064 import iaik.asn1.ObjectID;
065 import iaik.asn1.structures.AlgorithmID;
066 import iaik.asn1.structures.Attribute;
067 import iaik.cms.CMSAlgorithmID;
068 import iaik.cms.CMSException;
069 import iaik.cms.ContentInfo;
070 import iaik.cms.ContentInfoStream;
071 import iaik.cms.IssuerAndSerialNumber;
072 import iaik.cms.SignedData;
073 import iaik.cms.SignedDataStream;
074 import iaik.cms.SignerInfo;
075 import iaik.cms.attributes.CMSContentType;
076 import iaik.cms.attributes.SigningTime;
077 import iaik.utils.KeyAndCertificate;
078 import iaik.utils.Util;
079 import iaik.x509.X509Certificate;
080
081 import java.io.ByteArrayInputStream;
082 import java.io.ByteArrayOutputStream;
083 import java.io.IOException;
084 import java.io.InputStream;
085 import java.security.NoSuchAlgorithmException;
086 import java.security.PrivateKey;
087 import java.security.SignatureException;
088
089 import demo.DemoUtil;
090 import demo.cms.ecc.keystore.CMSEccKeyStore;
091
092
093 /**
094 * This class demonstrates the IAIK-CMS SignedData(Stream) implementation
095 * with the ECDSA (with SHA1, SHA224, SHA256, SHA384, SHA512, RIPEMD160) signature algorithm.
096 * <p>
097 * Any keys/certificates required for this demo are read from a keystore
098 * file "cmsecc.keystore" located in your current working directory. If
099 * the keystore file does not exist you can create it by running the
100 * {@link demo.cms.ecc.keystore.SetupCMSEccKeyStore SetupCMSEccKeyStore}
101 * program.
102 * <p>
103 * Additionally to <code>iaik_cms.jar</code> you also must have
104 * <code>iaik_jce_(full).jar</code> (IAIK-JCE, <a href =
105 * "https://sic.tech/products/core-crypto-toolkits/jca-jce/" target="_blank">
106 * https://sic.tech/products/core-crypto-toolkits/jca-jce/</a>),
107 * and <code>iaik_eccelarate.jar</code> (IAIK-ECCelerate<sup><small>TM</small></sup>, <a href =
108 * "https://sic.tech/products/core-crypto-toolkits/eccelerate/" target="_blank">
109 * https://sic.tech/products/core-crypto-toolkits/eccelerate/</a>)
110 * in your classpath.
111 */
112 public class ECDSASignedDataDemo {
113
114 /**
115 * Default Constructor.
116 */
117 public ECDSASignedDataDemo() throws Exception {
118 System.out.println();
119 System.out.println("**********************************************************************************");
120 System.out.println("* ECDSASignedData demo *");
121 System.out.println("* (shows how to use the SignedData(Stream) implementation with ECDSA) *");
122 System.out.println("**********************************************************************************");
123 System.out.println();
124
125 }
126
127 /**
128 * Creates an ECDSA signed CMS <code>SignedDataStream</code> object and wraps it by a
129 * CMS <code>ContentInfoStream</code>.
130 *
131 * @param message the message to be signed, as byte representation
132 * @param mode the transmission mode, either IMPLICIT or EXPLICIT
133 * @param hashAlgorithm the hash algorithm to be used
134 * @param signatureAlgorithm the signature algorithm to be used
135 * @param signerKey the private key of the signer
136 * @param certificates the certificate chain of the signer
137 *
138 * @return the DER encoding of the <code>ContentInfo</code> object just created
139 *
140 * @throws CMSException if the <code>SignedData</code>, <code>ContentInfo</code>
141 * object cannot be created
142 * @throws IOException if an I/O related error occurs
143 */
144 public byte[] createSignedDataStream(byte[] message,
145 int mode,
146 AlgorithmID hashAlgorithm,
147 AlgorithmID signatureAlgorithm,
148 PrivateKey signerKey,
149 X509Certificate[] certificates)
150 throws CMSException, IOException {
151
152 System.out.print("Create a new message signed with " + signatureAlgorithm.getName());
153
154 // we are testing the stream interface
155 ByteArrayInputStream is = new ByteArrayInputStream(message);
156 // create a new SignedData object which includes the data
157 SignedDataStream signed_data = new SignedDataStream(is, mode);
158
159 // SignedData shall include the certificate chain for verifying
160 signed_data.setCertificates(certificates);
161
162 // cert at index 0 is the user certificate
163 IssuerAndSerialNumber issuer = new IssuerAndSerialNumber(certificates[0]);
164
165 // create a new SignerInfo
166 AlgorithmID ecdsaSig = (AlgorithmID)signatureAlgorithm.clone();
167 // CMS-ECDSA requires to encode the parameter field as NULL (see RFC 3278)
168 ecdsaSig.encodeAbsentParametersAsNull(true);
169 SignerInfo signer_info = new SignerInfo(issuer, (AlgorithmID)hashAlgorithm.clone(), ecdsaSig, signerKey);
170
171 try {
172 // create some signed attributes
173 // the message digest attribute is automatically added
174 Attribute[] attributes = new Attribute[2];
175 // content type is data
176 CMSContentType contentType = new CMSContentType(ObjectID.cms_data);
177 attributes[0] = new Attribute(contentType);
178 // signing time is now
179 SigningTime signingTime = new SigningTime();
180 attributes[1] = new Attribute(signingTime);
181
182 // set the attributes
183 signer_info.setSignedAttributes(attributes);
184 } catch (Exception ex) {
185 throw new CMSException("Error adding attributes: " + ex.toString());
186 }
187
188 // finish the creation of SignerInfo by calling method addSigner
189 try {
190 signed_data.addSignerInfo(signer_info);
191 } catch (NoSuchAlgorithmException ex) {
192 throw new CMSException("No implementation for signature algorithm: "+ex.getMessage());
193 }
194
195 // write the data through SignedData to any out-of-band place
196 if (mode == SignedDataStream.EXPLICIT) {
197 InputStream data_is = signed_data.getInputStream();
198 byte[] buf = new byte[1024];
199 int r;
200 while ((r = data_is.read(buf)) > 0) {
201 ; // skip data
202 }
203 }
204
205 signed_data.setBlockSize(2048);
206 // create the ContentInfo
207 ContentInfoStream cis = new ContentInfoStream(signed_data);
208 // return the SignedData as DER encoded byte array with block size 2048
209 ByteArrayOutputStream os = new ByteArrayOutputStream();
210 cis.writeTo(os);
211 return os.toByteArray();
212 }
213
214
215 /**
216 * Parses a CMS <code>ContentInfo</code> object holding a <code>SignedData</code>
217 * object and verifies the signature.
218 *
219 * @param signedData the <code>ContentInfo</code> holding the <code>SignedData</code>
220 * object as BER encoded byte array
221 * @param message the the message which was transmitted out-of-band (explicit signed)
222 * @param certificates the certificate of the signer (used for alternative signature verification)
223 *
224 * @return the inherent message as byte array
225 *
226 * @throws CMSException if any signature does not verify
227 * @throws IOException if an I/O related error occurs
228 */
229 public byte[] getSignedDataStream(byte[] signedData, byte[] message, X509Certificate[] certificates)
230 throws CMSException, IOException {
231
232 // we are testing the stream interface
233 ByteArrayInputStream is = new ByteArrayInputStream(signedData);
234
235 SignedDataStream signed_data = new SignedDataStream(is);
236
237 if (signed_data.getMode() == SignedDataStream.EXPLICIT) {
238 // in explicit mode explicitly supply the content for hash computation
239 signed_data.setInputStream(new ByteArrayInputStream(message));
240 }
241
242 // get an InputStream for reading the signed content and update hash computation
243 InputStream data = signed_data.getInputStream();
244 ByteArrayOutputStream os = new ByteArrayOutputStream();
245 Util.copyStream(data, os, null);
246
247 System.out.println("SignedData contains the following signer information:");
248 SignerInfo[] signer_infos = signed_data.getSignerInfos();
249
250 int numberOfSignerInfos = signer_infos.length;
251 if (numberOfSignerInfos == 0) {
252 String warning = "Warning: Unsigned message (no SignerInfo included)!";
253 System.err.println(warning);
254 throw new CMSException(warning);
255 } else {
256 for (int i = 0; i < numberOfSignerInfos; i++) {
257 try {
258 // verify the signed data using the SignerInfo at index i
259 X509Certificate signer_cert = signed_data.verify(i);
260 // if the signature is OK the certificate of the signer is returned
261 System.out.println("Signature OK from signer: "+signer_cert.getSubjectDN());
262 // check for some included attributes
263 SigningTime signingTime = (SigningTime)signer_infos[i].getSignedAttributeValue(ObjectID.signingTime);
264 if (signingTime != null) {
265 System.out.println("This message has been signed at " + signingTime.get());
266 }
267 CMSContentType contentType = (CMSContentType)signer_infos[i].getSignedAttributeValue(ObjectID.contentType);
268 if (contentType != null) {
269 System.out.println("The content has CMS content type " + contentType.get().getName());
270 }
271 } catch (SignatureException ex) {
272 // if the signature is not OK a SignatureException is thrown
273 System.out.println("Signature ERROR from signer: "+signed_data.getCertificate(signer_infos[i].getSignerIdentifier()).getSubjectDN());
274 throw new CMSException(ex.toString());
275 }
276 }
277 // now check alternative signature verification
278 System.out.println("Now check the signature assuming that no certs have been included:");
279 try {
280 SignerInfo signer_info = signed_data.verify(certificates[0]);
281 // if the signature is OK the certificate of the signer is returned
282 System.out.println("Signature OK from signer: "+signed_data.getCertificate(signer_info.getSignerIdentifier()).getSubjectDN());
283 } catch (SignatureException ex) {
284 // if the signature is not OK a SignatureException is thrown
285 System.out.println("Signature ERROR from signer: "+certificates[0].getSubjectDN());
286 throw new CMSException(ex.toString());
287 }
288 // in practice we also would validate the signer certificate(s)
289 }
290 return os.toByteArray();
291 }
292
293
294 /**
295 * Creates an ECDSA signed CMS <code>SignedData</code> object and wraps it by a CMS
296 * <code>ContentInfo</code> object.
297 * <p>
298 *
299 * @param message the message to be signed, as byte representation
300 * @param mode the mode, either SignedData.IMPLICIT or SignedData.EXPLICIT
301 * @param hashAlgorithm the hash algorithm to be used
302 * @param signatureAlgorithm the signature algorithm to be used
303 * @param signerKey the private key of the signer
304 * @param certificates the certificate chain of the signer
305 *
306 * @return the DER encoded <code>SignedData</code>-<code>ContentInfo</code> object
307 *
308 * @throws CMSException if the <code>SignedData</code>-<code>ContentInfo</code> object cannot
309 * be created
310 * @throws IOException if an I/O related error occurs
311 */
312 public byte[] createSignedData(byte[] message,
313 int mode,
314 AlgorithmID hashAlgorithm,
315 AlgorithmID signatureAlgorithm,
316 PrivateKey signerKey,
317 X509Certificate[] certificates)
318 throws CMSException, IOException {
319
320 System.out.println("Create a new message signed with " + signatureAlgorithm.getName());
321
322 // create a new SignedData object which includes the data
323 SignedData signed_data = new SignedData(message, mode);
324
325 // SignedData shall include the certificate chain for verifying
326 signed_data.setCertificates(certificates);
327
328 // cert at index 0 is the user certificate
329 IssuerAndSerialNumber issuer = new IssuerAndSerialNumber(certificates[0]);
330
331 // create a new SignerInfo
332 AlgorithmID ecdsaSig = (AlgorithmID)signatureAlgorithm.clone();
333 // CMS-ECC requires that the parameters field is encoded as ASN.1 NULL object (see RFC 3278)
334 ecdsaSig.encodeAbsentParametersAsNull(true);
335 SignerInfo signer_info = new SignerInfo(issuer, (AlgorithmID)hashAlgorithm.clone(), ecdsaSig, signerKey);
336
337 try {
338 // create some signed attributes
339 // the message digest attribute is automatically added
340 Attribute[] attributes = new Attribute[2];
341 // content type is data
342 CMSContentType contentType = new CMSContentType(ObjectID.cms_data);
343 attributes[0] = new Attribute(contentType);
344 // signing time is now
345 SigningTime signingTime = new SigningTime();
346 attributes[1] = new Attribute(signingTime);
347
348 // set the attributes
349 signer_info.setSignedAttributes(attributes);
350 } catch (Exception ex) {
351 throw new CMSException("Error adding attributes: " + ex.toString());
352 }
353
354 // finish the creation of SignerInfo by calling method addSigner
355 try {
356 signed_data.addSignerInfo(signer_info);
357 } catch (NoSuchAlgorithmException ex) {
358 throw new CMSException("No implementation for signature algorithm: "+ex.getMessage());
359 }
360
361 ContentInfo ci = new ContentInfo(signed_data);
362 return ci.getEncoded();
363 }
364
365
366 /**
367 * Parses a CMS <code>ContentInfo</code> holding a <code>SignedData</code>
368 * object and verifies the signature.
369 *
370 * @param signedData the <code>ContentInfo</code> holding the <code>SignedData</code>
371 * object as DER encoded byte array
372 * @param message the message which was transmitted out-of-band (explicit signed)
373 * @param certificates the certificate of the signer (used for alternative signature verification)
374 *
375 * @return the inherent message as byte array
376 *
377 * @throws CMSException if any signature does not verify
378 * @throws IOException if an I/O related error occurs
379 */
380 public byte[] getSignedData(byte[] signedData, byte[] message, X509Certificate[] certificates)
381 throws CMSException, IOException {
382
383 ByteArrayInputStream is = new ByteArrayInputStream(signedData);
384 // create the SignedData object
385 SignedData signed_data = new SignedData(is);
386
387 if (signed_data.getMode() == SignedData.EXPLICIT) {
388 // in explcit mode explictly supply the content data to do the hash calculation
389 signed_data.setContent(message);
390 }
391
392 System.out.println("SignedData contains the following signer information:");
393 SignerInfo[] signer_infos = signed_data.getSignerInfos();
394
395 int numberOfSignerInfos = signer_infos.length;
396 if (numberOfSignerInfos == 0) {
397 String warning = "Warning: Unsigned message (no SignerInfo included)!";
398 System.err.println(warning);
399 throw new CMSException(warning);
400 } else {
401 for (int i = 0; i < numberOfSignerInfos; i++) {
402 try {
403 // verify the signed data using the SignerInfo at index i
404 X509Certificate signer_cert = signed_data.verify(i);
405 // if the signature is OK the certificate of the signer is returned
406 System.out.println("Signature OK from signer: "+signer_cert.getSubjectDN());
407 // check some attributes
408 SigningTime signingTime = (SigningTime)signer_infos[i].getSignedAttributeValue(ObjectID.signingTime);
409 if (signingTime != null) {
410 System.out.println("This message has been signed at " + signingTime.get());
411 }
412 CMSContentType contentType = (CMSContentType)signer_infos[i].getSignedAttributeValue(ObjectID.contentType);
413 if (contentType != null) {
414 System.out.println("The content has CMS content type " + contentType.get().getName());
415 }
416 } catch (SignatureException ex) {
417 // if the signature is not OK a SignatureException is thrown
418 System.out.println("Signature ERROR from signer: "+signed_data.getCertificate(signer_infos[i].getSignerIdentifier()).getSubjectDN());
419 throw new CMSException(ex.toString());
420 }
421 }
422
423 // now check alternative signature verification
424 System.out.println("Now check the signature assuming that no certs have been included:");
425 try {
426 SignerInfo signer_info = signed_data.verify(certificates[0]);
427 // if the signature is OK the certificate of the signer is returned
428 System.out.println("Signature OK from signer: "+signed_data.getCertificate(signer_info.getSignerIdentifier()).getSubjectDN());
429 } catch (SignatureException ex) {
430 // if the signature is not OK a SignatureException is thrown
431 System.out.println("Signature ERROR from signer: "+certificates[0].getSubjectDN());
432 throw new CMSException(ex.toString());
433 }
434 // in practice we also would validate the signer certificate(s)
435 }
436 return signed_data.getContent();
437 }
438
439 /**
440 * Runs the signing - verifying demo.
441 *
442 * @param message the message to be signed
443 * @param hashAlgorithm the hash algorithm to be used
444 * @param signatureAlgorithm the signature algorithm to be used
445 * @param signerKeyAndCert private key and certificate chain of the signer
446 */
447 public void runDemo(byte[] message,
448 AlgorithmID hashAlgorithm,
449 AlgorithmID signatureAlgorithm,
450 KeyAndCertificate signerKeyAndCert)
451 throws Exception {
452
453 PrivateKey signerKey = signerKeyAndCert.getPrivateKey();
454 X509Certificate[] signerCerts = signerKeyAndCert.getCertificateChain();
455
456 byte[] encodedSignedData;
457 byte[] received_message = null;
458
459 System.out.println("\nRun demos for " + hashAlgorithm.getName()
460 + " / " + signatureAlgorithm.getName()
461 + " for " + signerCerts[0].getSubjectDN()
462 + "\n");
463
464 System.out.println("Stream implementation demos");
465 System.out.println("===========================");
466 //
467 // test CMS Implicit SignedDataStream
468 //
469 System.out.println("\nImplicit SignedDataStream demo [create]:\n");
470 encodedSignedData = createSignedDataStream(message,
471 SignedDataStream.IMPLICIT,
472 hashAlgorithm,
473 signatureAlgorithm,
474 signerKey,
475 signerCerts);
476 System.out.println();
477
478 // transmit data
479 System.out.println("\nImplicit SignedDataStream demo [parse]:\n");
480 received_message = getSignedDataStream(encodedSignedData, null, signerCerts);
481 System.out.print("\nSigned content: ");
482 System.out.println(new String(received_message));
483
484 //
485 // test CMS Explicit SignedDataStream
486 //
487 System.out.println("\nExplicit SignedDataStream demo [create]:\n");
488 encodedSignedData = createSignedDataStream(message,
489 SignedDataStream.EXPLICIT,
490 hashAlgorithm,
491 signatureAlgorithm,
492 signerKey,
493 signerCerts);
494 // transmit data
495 System.out.println("\nExplicit SignedDataStream demo [parse]:\n");
496 received_message = getSignedDataStream(encodedSignedData, message, signerCerts);
497 System.out.print("\nSigned content: ");
498 System.out.println(new String(received_message));
499
500 // the non-stream implementation
501 System.out.println("\nNon-stream implementation demos");
502 System.out.println("===============================");
503
504 //
505 // test CMS Implicit SignedData
506 //
507 System.out.println("\nImplicit CMS SignedData demo [create]:\n");
508 encodedSignedData = createSignedData(message,
509 SignedData.IMPLICIT,
510 hashAlgorithm,
511 signatureAlgorithm,
512 signerKey,
513 signerCerts);
514 // transmit data
515 System.out.println("\nImplicit CMS SignedData demo [parse]:\n");
516 received_message = getSignedData(encodedSignedData, null, signerCerts);
517 System.out.print("\nSigned content: ");
518 System.out.println(new String(received_message));
519
520 //
521 // test CMS Explicit SignedData
522 //
523 System.out.println("\nExplicit CMS SignedData demo [create]:\n");
524 encodedSignedData = createSignedData(message,
525 SignedData.EXPLICIT,
526 hashAlgorithm,
527 signatureAlgorithm,
528 signerKey,
529 signerCerts);
530 // transmit data
531 System.out.println("\nExplicit CMS SignedData demo [parse]:\n");
532 received_message = getSignedData(encodedSignedData, message, signerCerts);
533 System.out.print("\nSigned content: ");
534 System.out.println(new String(received_message));
535
536 }
537
538 /**
539 * Tests the CMS SignedData implementation with the ECDSA signature
540 * algorithm and several hash algorithms.
541 */
542 public void start() throws Exception {
543
544 // the test message
545 String m = "This is the test message.";
546 System.out.println("Test message: \""+m+"\"");
547 System.out.println();
548 byte[] message = m.getBytes();
549
550 AlgorithmID[][] algorithms = new AlgorithmID[][] {
551 { CMSAlgorithmID.sha1, CMSAlgorithmID.ecdsa_With_SHA1 },
552 { CMSAlgorithmID.sha224, CMSAlgorithmID.ecdsa_With_SHA224 },
553 { CMSAlgorithmID.sha256, CMSAlgorithmID.ecdsa_With_SHA256 },
554 { CMSAlgorithmID.sha384, CMSAlgorithmID.ecdsa_With_SHA384 },
555 { CMSAlgorithmID.sha512, CMSAlgorithmID.ecdsa_With_SHA512 },
556 // ECDSA with RIPEMD-160 in plain format (BSI)
557 { CMSAlgorithmID.ripeMd160, CMSAlgorithmID.ecdsa_plain_With_RIPEMD160 },
558
559 };
560
561 // get signer key and certs
562 KeyAndCertificate[] keyAndCerts = {
563 // P-192
564 new KeyAndCertificate(CMSEccKeyStore.getPrivateKey(CMSEccKeyStore.ECDSA, CMSEccKeyStore.SZ_192_SIGN),
565 CMSEccKeyStore.getCertificateChain(CMSEccKeyStore.ECDSA, CMSEccKeyStore.SZ_192_SIGN)),
566 // P-224
567 new KeyAndCertificate(CMSEccKeyStore.getPrivateKey(CMSEccKeyStore.ECDSA, CMSEccKeyStore.SZ_224_SIGN),
568 CMSEccKeyStore.getCertificateChain(CMSEccKeyStore.ECDSA, CMSEccKeyStore.SZ_224_SIGN)),
569 // P-256
570 new KeyAndCertificate(CMSEccKeyStore.getPrivateKey(CMSEccKeyStore.ECDSA, CMSEccKeyStore.SZ_256_SIGN),
571 CMSEccKeyStore.getCertificateChain(CMSEccKeyStore.ECDSA, CMSEccKeyStore.SZ_256_SIGN)),
572 // P-384
573 new KeyAndCertificate(CMSEccKeyStore.getPrivateKey(CMSEccKeyStore.ECDSA, CMSEccKeyStore.SZ_384_SIGN),
574 CMSEccKeyStore.getCertificateChain(CMSEccKeyStore.ECDSA, CMSEccKeyStore.SZ_384_SIGN)),
575 // P-521
576 new KeyAndCertificate(CMSEccKeyStore.getPrivateKey(CMSEccKeyStore.ECDSA, CMSEccKeyStore.SZ_521_SIGN),
577 CMSEccKeyStore.getCertificateChain(CMSEccKeyStore.ECDSA, CMSEccKeyStore.SZ_521_SIGN)),
578 // (for ECDSA with RIPEMD-160 in plain format (BSI)
579 new KeyAndCertificate(CMSEccKeyStore.getPrivateKey(CMSEccKeyStore.ECDSA, CMSEccKeyStore.SZ_192_SIGN),
580 CMSEccKeyStore.getCertificateChain(CMSEccKeyStore.ECDSA, CMSEccKeyStore.SZ_192_SIGN)),
581 };
582
583 KeyAndCertificate[] brainpoolKeyAndCerts = {
584 // Brainpool P-192
585 new KeyAndCertificate(CMSEccKeyStore.getPrivateKey(CMSEccKeyStore.ECDSA, CMSEccKeyStore.SZ_192_BRAINPOOL_SIGN),
586 CMSEccKeyStore.getCertificateChain(CMSEccKeyStore.ECDSA, CMSEccKeyStore.SZ_192_BRAINPOOL_SIGN)),
587 // Brainpool P-224
588 new KeyAndCertificate(CMSEccKeyStore.getPrivateKey(CMSEccKeyStore.ECDSA, CMSEccKeyStore.SZ_224_BRAINPOOL_SIGN),
589 CMSEccKeyStore.getCertificateChain(CMSEccKeyStore.ECDSA, CMSEccKeyStore.SZ_224_BRAINPOOL_SIGN)),
590 // Brainpool P-256
591 new KeyAndCertificate(CMSEccKeyStore.getPrivateKey(CMSEccKeyStore.ECDSA, CMSEccKeyStore.SZ_256_BRAINPOOL_SIGN),
592 CMSEccKeyStore.getCertificateChain(CMSEccKeyStore.ECDSA, CMSEccKeyStore.SZ_256_BRAINPOOL_SIGN)),
593 // Brainpool P-384
594 new KeyAndCertificate(CMSEccKeyStore.getPrivateKey(CMSEccKeyStore.ECDSA, CMSEccKeyStore.SZ_384_BRAINPOOL_SIGN),
595 CMSEccKeyStore.getCertificateChain(CMSEccKeyStore.ECDSA, CMSEccKeyStore.SZ_384_BRAINPOOL_SIGN)),
596 // Brainpool P-512
597 new KeyAndCertificate(CMSEccKeyStore.getPrivateKey(CMSEccKeyStore.ECDSA, CMSEccKeyStore.SZ_512_BRAINPOOL_SIGN),
598 CMSEccKeyStore.getCertificateChain(CMSEccKeyStore.ECDSA, CMSEccKeyStore.SZ_512_BRAINPOOL_SIGN)),
599
600
601 };
602
603 final int HASH_ALG = 0;
604 final int SIGNATURE_ALG = 1;
605 for (int i = 0; i < keyAndCerts.length; i++) {
606 runDemo(message, algorithms[i][HASH_ALG], algorithms[i][SIGNATURE_ALG], keyAndCerts[i]);
607 }
608 // brainpool
609 for (int i = 0; i < brainpoolKeyAndCerts.length; i++) {
610 runDemo(message, algorithms[i][HASH_ALG], algorithms[i][SIGNATURE_ALG], brainpoolKeyAndCerts[i]);
611 }
612
613 }
614
615 /**
616 * Starts the demo.
617 *
618 * @throws Exception
619 * if an error occurs
620 */
621 public static void main(String argv[]) throws Exception {
622
623 DemoUtil.initDemos();
624 ECCDemoUtil.installIaikEccProvider();
625 (new ECDSASignedDataDemo()).start();
626 System.out.println("\nReady!");
627 System.in.read();
628 }
629
630 }