001: /*
002: *
003: *
004: * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: */
026:
027: package javax.microedition.securityservice;
028:
029: import javax.microedition.securityservice.CMSMessageSignatureServiceException;
030: import javax.microedition.pki.UserCredentialManagerException;
031: import com.sun.midp.security.*;
032:
033: import com.sun.midp.main.Configuration;
034:
035: /**
036: * Provides signature services for cryptographic messages.
037: * <p>
038: * Cryptographic operations are frequently required to realize
039: * authentication, authorization, integrity, and privacy services.
040: * These services may be provided at various layers (for example,
041: * communication layer, application layer, and so on). These services
042: * form critical security components of larger systems
043: * and services such as e-commerce, e-government, or corporate
044: * applications. The layer at which these services are used are
045: * governed by the security requirements of the system and the policies
046: * used to formulate those requirements.
047: * </p>
048: *
049: * <p>
050: * The services of authentication and authorization are often delivered
051: * through the use of digital signatures. For a
052: * digital signature to be useful, it must be possible to determine
053: * what was signed, which algorithms were used, and who generated the
054: * signature. Additional information may be included. The combination of
055: * this information into a single construct is referred to as a formatted
056: * digital signature.
057: * </p>
058: *
059: * <p>
060: * A formatted digital signature is well suited to deliver the services
061: * of authentication, authorization, and integrity of information at the
062: * application layer within numerous systems. The generation of a formatted
063: * digital signature involves the use of multiple cryptographic
064: * operations including random number generation, hash generation, and the
065: * application of a suitable signature algorithm. The cryptographic
066: * operations are often performed on a security element that is trusted for
067: * secure storage of cryptographic keys and secure computation of cryptographic
068: * operations. The result of these cryptographic operations is combined with
069: * information such as the user's identity and the data on which the
070: * cryptographic operations are performed. This is then combined and presented
071: * in a specific format that is expressed in ASN.1 or XML. The result is
072: * referred to as a formatted digital signature. Examples of formatted digital
073: * signatures include PKCS#7, CMS, and XML Digital Signature. This
074: * class supports
075: * signature messages that conform to the Cryptographic Message Syntax
076: * (CMS) format as specified in
077: * <a href="http://www.ietf.org/rfc/rfc2630.txt">RFC 2630</a>
078: * with enhanced security services for
079: * <a href="http://www.ietf.org/rfc/rfc2634.txt">RFC 2634</a>.
080: * </p>
081: *
082: * <p>
083: * The complexity of generating a formatted digital signature is reduced
084: * through the use of a high-level interface. The implementation
085: * is responsible for identifying and managing the appropriate security
086: * elements, requesting the required cryptographic operations from the system
087: * and security element, as well as performing the appropriate formatting of the
088: * results. The advantages of this interface is twofold. First, the
089: * complexity of
090: * generating a formatted digital signature is removed from the application
091: * developer. Second, the size of the implementation can be
092: * drastically reduced, removing
093: * the need for separate packages to access and manage security elements,
094: * perform specific cryptographic operations, and formatting the results
095: * appropriately.
096: * </p>
097: *
098: * <p>
099: * This class provides a compact and high-level cryptographic
100: * interface that utilizes security elements available on a J2ME device.
101: * </p>
102: *
103: * <p>
104: * In this version of the interface, signature generation is defined for
105: * authentication and authorization purposes. The <code>sign</code>
106: * and <code>authenticate</code> methods return CMS-formatted
107: * signatures. The signed message can be constructed with content
108: * included (opaque signature) or without the content (detached
109: * signature).
110: * </p>
111: *
112: * <p>
113: * For the purpose of this interface, a security element is a device
114: * or part of a
115: * device that is trusted to provide secure storage of user credentials
116: * and certificates as well as cryptographic keys. In addition, such a
117: * device is trusted to perform secure computation involving
118: * the cryptographic keys that are securely stored on the device.
119: * If a requested security element can not be found, a
120: * <code>UserCredentialManagerException</code> is thrown and
121: * the <code>getReason</code> method MUST return
122: * <code>UserCredentialManagerException.SE_NOT_FOUND</code>.
123: * </p>
124: *
125: * <p>
126: * A device may have multiple security elements. The security elements may be
127: * removable. Public information such as the user credential and a reference to
128: * the corresponding security element may be cached on the J2ME device.
129: * </p>
130: *
131: * <p>
132: * Authorization of the use of a key in a security element will be governed by
133: * the policy of the security element (for example, no authorization
134: * required, PIN
135: * entry required, biometric required, and so on).
136: * </p>
137: *
138: * <p>
139: * Cryptographic keys may be marked for different purposes, such as
140: * non-repudiation
141: * or authentication. The implementation will honor the key
142: * usage defined
143: * by a security element.
144: * </p>
145: *
146: * <p>
147: * This class honors the key usage policy defined by the security
148: * element by splitting
149: * the generation of formatted digital signatures between two methods,
150: * namely the
151: * <code>sign</code> and <code>authenticate</code> methods. The sign method is
152: * associated with keys marked for digital signature and non-repudiation. The
153: * authenticate method is associated with keys marked for digital
154: * signature only,
155: * or digital signature and a key usage apart from non-repudiation (such as
156: * authentication).
157: * </p>
158: *
159: * <p>
160: * These two methods, apart from being associated with a specific key
161: * usage, also have
162: * distinct behavior regarding user interaction. The
163: * <code>sign</code> method will always display the text that is
164: * about to be signed. The <code>authenticate</code> method
165: * is overloaded and does not display the data that is about to be
166: * signed, if that data is passed as a <code>byte</code> array. If the
167: * data that is about to be signed is passed as a <code>String</code>,
168: * it is always displayed.
169: * </p>
170: *
171: * <p>
172: * The <code>sign</code> method should be used for higher-value transactions and
173: * authorizations while the <code>authenticate</code> method should be used
174: * whenever a digital signature is required to authenticate a user.
175: * </p>
176: *
177: * <h2>Example Code</h2>
178: * <p>
179: * This is an example of how this interface may be used to generate a
180: * formatted digital
181: * signature used for authentication or non-repudiation purposes.
182: * </p>
183: * <pre>
184: *
185: * String caName = new String("cn=ca_name,ou=ou_name,o=org_name,c=ie");
186: * String[] caNames = new String[1];
187: * String stringToSign = new String("JSR 177 Approved");
188: * String userPrompt = new String("Please insert the security element "
189: * + "issued by bank ABC"
190: * + "for the application XYZ.");
191: * byte[] byteArrayToSign = new byte[8];
192: * byte[] authSignature;
193: * byte[] signSignature;
194: *
195: * caNames[0] = caName;
196: *
197: * try {
198: * // Generate a formatted authentication signature that includes the
199: * // content that was signed in addition to the certificate.
200: * // Selection of the key is implicit in selection of the certificate,
201: * // which is selected through the caNames parameter.
202: * // If the appropriate key is not found in any of the security
203: * // elements present in the device, the implementation may guide
204: * // the user to insert an alternative security element using
205: * // the securityElementPrompt parameter.
206: * authSignature = CMSMessageSignatureService.authenticate(
207: * byteArrayToSign,
208: * CMSMessageSignatureService.SIG_INCLUDE_CERTIFICATE
209: * |CMSMessageSignatureService.SIG_INCLUDE_CONTENT,
210: * caNames, userPrompt);
211: *
212: * // Generate a formatted signature that includes the
213: * // content that was signed in addition to the certificate.
214: * // Selection of the key is implicit in selection of the certificate,
215: * // which is selected through the caNames parameter.
216: * // If the appropriate key is not found in any of the
217: * // security elements present in the device, the implementation
218: * // may guide the user to insert an alternative
219: * // security element using the securityElementPrompt parameter.
220: * signSignature = CMSMessageSignatureService.sign(
221: * stringToSign,
222: * CMSMessageSignatureService.SIG_INCLUDE_CERTIFICATE
223: * |CMSMessageSignatureService.SIG_INCLUDE_CONTENT,
224: * caNames, userPrompt);
225: * } catch (IllegalArgumentException iae) {
226: * // Perform error handling
227: * iae.printStackTrace();
228: * } catch (CMSMessageSignatureServiceException ce) {
229: * if (ce.getReason() == ce.CRYPTO_FORMAT_ERROR) {
230: * System.out.println("Error formatting signature.");
231: * } else {
232: * System.out.println(ce.getMessage());
233: * }
234: * }
235: * ...
236: * </pre>
237: * <p>
238: * <h2>Note regarding UI implementations</h2>
239: * </p>
240: * <p>
241: * The user prompts and notifications should be implemented in such a way that:
242: * <ul>
243: * <li>
244: * the UI is distinguishable from a UI generated by external sources
245: * (for example J2ME applications)
246: * </li>
247: * <li>
248: * external sources are not able to modify the data presented to the user.
249: * </li>
250: * <li>
251: * external sources are not able to retrieve the PIN data.
252: * </li>
253: * </ul>
254: * </p>
255: */
256:
257: final public class CMSMessageSignatureService {
258: /**
259: * Includes the content that was signed in the signature.
260: * If this option is specified and the <code>sign</code>
261: * and <code>authenticate</code> methods do not support
262: * opaque signatures, a
263: * <code>CMSMessageSignatureServiceException</code>
264: * exception MUST be thrown and the
265: * <code>getReason</code> method
266: * MUST return the <code>CRYPTO_NO_OPAQUE_SIG</code>
267: * error code.
268: */
269: public static final int SIG_INCLUDE_CONTENT = 1;
270:
271: /**
272: * Includes the user certificate in the signature.
273: * If this option is specified and the certificate is not
274: * available, a
275: * <code>CMSMessageSignatureServiceException</code>
276: * exception MUST be thrown and the
277: * <code>getReason</code> method
278: * MUST return the <code>CRYPTO_NO_CERTIFICATE</code>
279: * error code.
280: */
281: public static final int SIG_INCLUDE_CERTIFICATE = 2;
282:
283: /** Unassigned option bits. */
284: static int mask = ~(SIG_INCLUDE_CONTENT | SIG_INCLUDE_CERTIFICATE);
285:
286: /**
287: * Indicates that certificate inclusion is supported
288: * on the platform.
289: */
290: private static boolean certSig = false;
291:
292: static {
293: String signprop = Configuration
294: .getProperty("com.sun.satsa.certsig");
295: if (signprop != null) {
296: certSig = signprop.equals("true");
297: }
298: }
299:
300: /**
301: * Constructor for the CMSMessageSignatureService class.
302: */
303: private CMSMessageSignatureService() {
304: }
305:
306: /**
307: * Generates a CMS signed message.
308: * <p>
309: * The signature may be generated using key pairs that are marked
310: * for non-repudiation. It is up to
311: * the implementation to search the available security
312: * elements for relevant keys. Selection of the appropriate
313: * key is facilitated by the <code>caNames</code>
314: * parameter. Only keys certified by the specified certificate
315: * authority will be eligible for key selection.
316: * If the appropriate key is not found in any of the security elements
317: * present in the device, the implementation may guide the user to
318: * insert an alternative security element using the
319: * <code>securityElementPrompt</code> parameter.
320: * </p>
321: *
322: * <p>
323: * The implementation MUST display the user friendly name of the
324: * certificate or the certificate URI to the user. If more than
325: * one certificate is found, the user MUST be presented with a
326: * list of certificate friendly names. It is up to the user to
327: * select the appropriate certificate based on the certificate
328: * friendly name.
329: * </p>
330: *
331: * <p>
332: * The signature format is controlled through the
333: * <code>options</code> parameter. If the
334: * <code>options</code> parameter is non-zero and is
335: * not a valid combination of
336: * <code>CMSMessageSignatureService.SIG_INCLUDE_CERTIFICATE</code>
337: * and
338: * <code>CMSMessageSignatureService.SIG_INCLUDE_CONTENT</code>,
339: * an <code>IllegalArgumentException</code> exception
340: * MUST be thrown.
341: * </p>
342: *
343: * <p>
344: * Before requesting confirmation of the signature through a
345: * PIN or some other means, the implementation of this method
346: * MUST display the <code>stringToSign</code> to the user.
347: * </p>
348: *
349: * <p>
350: * Authorization of the use of the private key to generate a
351: * signature is subject to the policy of the underlying
352: * security element.
353: * If signature authorization is required through the entry
354: * of a PIN, the implementation of this method is responsible
355: * for collecting the PIN from the user and presenting the
356: * PIN to the security element. Incorrect PIN entry is handled
357: * by the implementation. The number of retries following
358: * incorrect PIN entry is governed by the security element
359: * policy. If the PIN is blocked due to
360: * an excessive number of incorrect PIN entries, the
361: * implementation MUST throw a
362: * <code>SecurityException</code> exception.
363: * </p>
364: *
365: * <p>
366: * The signature MUST be generated on the UTF-8
367: * encoding of the <code>stringToSign</code>.
368: * </p>
369: *
370: * <p>
371: * The signature format returned by this method MUST follow
372: * the CMS <code><a href="http://www.ietf.org/rfc/rfc2630.txt">
373: * </a></code> signature format as specified in RFC2630.
374: * </p>
375: *
376: * @param stringToSign the string that is to be signed
377: * @param options the bitwise OR of the following options:
378: * <code>CMSMessageSignatureService.SIG_INCLUDE_CONTENT</code> and
379: * <code>CMSMessageSignatureService.SIG_INCLUDE_CERTIFICATE</code>.
380: * If the implementation
381: * does not support detached signatures
382: * (signatures without the original content),
383: * the absence of the
384: * <code>CMSMessageSignatureService.SIG_INCLUDE_CONTENT</code>
385: * option will result in a
386: * <code>CMSMessageSignatureServiceException</code> with a reason
387: * code of
388: * <code>CRYPTO_NO_DETACHED_SIG</code>. If the implementation
389: * does not support opaque signatures and the
390: * <code>CMSMessageSignatureService.SIG_INCLUDE_CONTENT</code>
391: * option is specified, a
392: * <code>CMSMessageSignatureServiceException</code>
393: * exception with a reason code of
394: * <code>CRYPTO_NO_OPAQUE_SIG</code> MUST be thrown. If
395: * certificate URIs are used instead of certificates and the
396: * <code>CMSMessageSignatureService.SIG_INCLUDE_CERTIFICATE</code>
397: * option is specified, a
398: * <code>CMSMessageSignatureServiceException</code> exception
399: * with a reason code of <code>CRYPTO_NO_CERTIFICATE</code>
400: * MUST be thrown.
401: *
402: * @param caNames an array of <code>String</code>s that
403: * contain the distinguished names of certification
404: * authorities that are trusted to issue certificates that
405: * may be used for authenticating a user.
406: * The distinguished name MUST be formatted according
407: * to <a href="http://www.ietf.org/rfc/rfc2253.txt">
408: * RFC 2253</a>. If this parameter is set to <code>null</code>
409: * or the array is empty,
410: * it is up to the implementation to interact with the user to
411: * select an appropriate certificate that may be used for
412: * digital signatures.
413: * If an entry in the <code>caNames</code> array is
414: * <code>null</code>, contains an empty String, or
415: * is not properly formatted according to RFC2253
416: * an <code>IllegalArgumentException</code>
417: * is thrown.
418: * If, for a given collection of <code>caNames</code> more than
419: * one certificate
420: * is available, a list of available certificates that are
421: * currently valid (i.e. not expired) MUST be displayed to the
422: * user for selection. The system clock MUST be used to determine
423: * the validity of certificates.
424: *
425: * @param securityElementPrompt guides a user to insert the
426: * correct security element if the security element is removable
427: * and not detected. If
428: * this parameter is set to <code>null</code> no information
429: * regarding which security element to use is displayed to
430: * the user.
431: * If there are no certificates that can be selected to
432: * complete the operation a
433: * <code>CMSMessageSignatureServiceException</code> is thrown
434: * and the <code>getReason</code> method
435: * MUST return the <code>CRYPTO_NO_CERTIFICATE</code>
436: * error code.
437: *
438: * @return the DER encoded signature,
439: * <code>null</code> if the signature generation was cancelled by
440: * the user before completion
441: * @throws CMSMessageSignatureServiceException if an
442: * error occurs during signature generation
443: * @throws IllegalArgumentException if the parameters are not
444: * valid
445: * @throws SecurityException if the caller is not
446: * authorized to sign messages
447: * @throws UserCredentialManagerException if a security element
448: * is not found
449: */
450: public static final byte[] sign(String stringToSign, int options,
451: String[] caNames, String securityElementPrompt)
452: throws CMSMessageSignatureServiceException,
453: UserCredentialManagerException {
454:
455: /* Validate the options selected. */
456: checkOptions(options);
457:
458: return com.sun.satsa.pki.PKIManager.sign(
459: com.sun.satsa.pki.PKIManager.SIGN_STRING, null,
460: stringToSign, options, caNames, securityElementPrompt);
461: }
462:
463: /**
464: * Generates a signature that may be used for
465: * authentication purposes. If the authentication signature is
466: * generated using public key technology, this method may be
467: * tied to key pairs marked for digital signature and
468: * authentication operations. It is
469: * up to the implementation to search the available security
470: * elements for relevant keys. Selection of the appropriate key is
471: * facilitated by the <code>caNames</code> parameter.
472: * If the appropriate key is not found in any of the security elements
473: * present in the device, the implementation may guide the user to
474: * insert an alternative security element using the
475: * <code>securityElementPrompt</code> parameter.
476: *
477: * <p>
478: * The implementation SHOULD display the user friendly name of the
479: * certificate or the certificate URI to the user. If more than
480: * one certificate is found, the user SHOULD be presented with a
481: * list of certificate friendly names. It is up to the user
482: * to select the appropriate certificate based on the certificate
483: * friendly name.
484: * </p>
485: *
486: *
487: * <p>
488: * The signature format is controlled through the
489: * <code>options</code> parameter. If the
490: * <code>options</code> parameter is non-zero and is
491: * not a valid combination of
492: * <code>CMSMessageSignatureService.SIG_INCLUDE_CERTIFICATE</code>
493: * and
494: * <code>CMSMessageSignatureService.SIG_INCLUDE_CONTENT</code>,
495: * an <code>IllegalArgumentException</code> exception
496: * MUST be thrown.
497: * </p>
498: *
499: * <p>
500: * Authorization of the use of the private key to generate a
501: * signature is subject to the policy of the underlying
502: * security element.
503: * If signature authorization is required through the entry of
504: * PIN, the implementation of this method is responsible for
505: * collecting the PIN from the user and presenting the PIN to
506: * the security element. Incorrect PIN entry is handled
507: * by the implementation. The number of retries following
508: * incorrect PIN entry is governed by the security element
509: * policy. If the PIN is blocked due to
510: * an excessive number of incorrect PIN entries, the
511: * implementation MUST throw a
512: * <code>SecurityException</code> exception.
513: * </p>
514: *
515: * <p>
516: * This method does not display the data that is about to be
517: * signed. The fact that a user is blindly signing information
518: * introduces the risk of a man-in-the-middle attack. For this
519: * reason it is recommended that access to this method is
520: * controlled using the standard access control mechanisms as
521: * defined by MIDP.
522: * </p>
523: *
524: * <p>
525: * The signature format returned by this method MUST follow
526: * the CMS <code><a href=http://www.ietf.org/rfc/rfc2630.txt>
527: * </a></code> signature format as specified in RFC 2630.
528: * </p>
529: *
530: * @param byteArrayToAuthenticate the byte array that is to be signed
531: * @param options the bitwise OR of the following options:
532: * <code>CMSMessageSignatureService.SIG_INCLUDE_CONTENT</code> and
533: * <code>CMSMessageSignatureService.SIG_INCLUDE_CERTIFICATE</code>.
534: * If the implementation
535: * does not support detached signatures
536: * (signatures without the original content),
537: * the absence of the
538: * <code>CMSMessageSignatureService.SIG_INCLUDE_CONTENT</code>
539: * option will result in a
540: * <code>CMSMessageSignatureServiceException</code> with a reason
541: * code of
542: * <code>CRYPTO_NO_DETACHED_SIG</code>. If the implementation
543: * does not support opaque signatures and the
544: * <code>CMSMessageSignatureService.SIG_INCLUDE_CONTENT</code>
545: * option is specified, a
546: * <code>CMSMessageSignatureServiceException</code>
547: * exception with a reason code of
548: * <code>CRYPTO_NO_OPAQUE_SIG</code> MUST be thrown. If
549: * certificate URIs are used instead of certificates and the
550: * <code>CMSMessageSignatureService.SIG_INCLUDE_CERTIFICATE</code>
551: * option is specified, a
552: * <code>CMSMessageSignatureServiceException</code> exception
553: * with a reason code of <code>CRYPTO_NO_CERTIFICATE</code>
554: * MUST be thrown.
555: *
556: * @param caNames an array of <code>String</code>s that
557: * contain the distinguished names of certification
558: * authorities that are trusted to issue certificates that
559: * may be used for authenticating a user.
560: * The distinguished name MUST be formatted according
561: * to <a href="http://www.ietf.org/rfc/rfc2253.txt">
562: * RFC 2253</a>. If this parameter is set to <code>null</code>
563: * or the array is empty,
564: * it is up to the implementation to interact with the user to
565: * select an appropriate certificate that may be used for
566: * authentication.
567: * If an entry in the <code>caNames</code> array is
568: * <code>null</code>, contains an empty String, or
569: * is not properly formatted according to RFC2253
570: * an <code>IllegalArgumentException</code>
571: * is thrown.
572: * If, for a given collection of <code>caNames</code> more than
573: * one certificate
574: * is available, a list of available certificates that are
575: * currently valid (i.e. not expired) MUST be displayed to the
576: * user for selection. The system clock MUST be used to determine
577: * the validity of certificates.
578: *
579: * @param securityElementPrompt guides a user to insert the
580: * correct security element if the security element is removable
581: * and not detected. If
582: * this parameter is set to <code>null</code> no information
583: * regarding which security element to use is displayed to
584: * the user.
585: * If there are no certificates that can be selected to
586: * complete the operation a
587: * <code>CMSMessageSignatureServiceException</code> is thrown
588: * and the <code>getReason</code> method
589: * MUST return the <code>CRYPTO_NO_CERTIFICATE</code>
590: * error code.
591: *
592: * @return the DER encoded signature,
593: * <code>null</code> if the signature generation was cancelled by
594: * the user before completion
595: * @throws CMSMessageSignatureServiceException if an
596: * error occurs during signature generation
597: * @throws IllegalArgumentException if the parameters are not
598: * valid
599: * @throws SecurityException if the caller is not
600: * authorized to generate authentication messages
601: * @throws UserCredentialManagerException if a security element
602: * is not found
603: */
604: public static final byte[] authenticate(
605: byte[] byteArrayToAuthenticate, int options,
606: String[] caNames, String securityElementPrompt)
607: throws CMSMessageSignatureServiceException,
608: UserCredentialManagerException {
609:
610: /* Validate the options selected. */
611: checkOptions(options);
612:
613: return com.sun.satsa.pki.PKIManager.sign(
614: com.sun.satsa.pki.PKIManager.AUTHENTICATE_DATA,
615: byteArrayToAuthenticate, null, options, caNames,
616: securityElementPrompt);
617: }
618:
619: /**
620: * Generates a signature that may be used for
621: * authentication purposes. If the authentication signature is
622: * generated using public key technology,
623: * this method may be tied to key pairs
624: * marked for digital signature and authentication operations. It is
625: * up to the implementation to search the available security
626: * elements for relevant keys. Selection of the appropriate key is
627: * facilitated by the <code>caNames</code> parameter.
628: * If the appropriate key is not found in any of the security elements
629: * present in the device, the implementation may guide the user to
630: * insert an alternative security element using the
631: * <code>securityElementPrompt</code> parameter.
632: *
633: * <p>
634: * The implementation MUST display the user friendly name of the
635: * certificate or the certificate URI to the user. If more than
636: * one certificate is found, the user MUST be presented with a
637: * list of certificate friendly names. It is up to the user to
638: * select the appropriate certificate based on the certificate
639: * friendly name.
640: * </p>
641: *
642: * <p>
643: * The signature format is controlled through the
644: * <code>options</code> parameter. If the
645: * <code>options</code> parameter is non-zero and is
646: * not a valid combination of
647: * <code>CMSMessageSignatureService.SIG_INCLUDE_CERTIFICATE</code>
648: * and
649: * <code>CMSMessageSignatureService.SIG_INCLUDE_CONTENT</code>,
650: * an <code>IllegalArgumentException</code> exception
651: * MUST be thrown.
652: * </p>
653: *
654: * <p>
655: * Before requesting confirmation of the signature through a
656: * PIN or some other means, the implementation of this method
657: * MUST display the <code>stringToAuthenticate</code> to the user.
658: * </p>
659: *
660: * <p>
661: * Authorization to use a private key to generate a
662: * signature is subject to the policy of the underlying
663: * security element.
664: * If signature authorization is required through the entry of a
665: * PIN, the implementation of this method is responsible for
666: * collecting the PIN from the user and presenting the PIN to
667: * the security element. Incorrect PIN entry is handled
668: * by the implementation. The number of retries following an
669: * incorrect PIN entry is governed by the security element
670: * policy. If the PIN is blocked due to
671: * an excessive number of incorrect PIN entries, the
672: * implementation MUST throw a
673: * <code>SecurityException</code> exception.
674: * </p>
675: *
676: * <p>
677: * The signature MUST be generated on the UTF-8
678: * encoding of the <code>stringToAuthenticate</code>.
679: * </p>
680: *
681: * <p>
682: * The signature format returned by this method MUST follow
683: * the CMS <code><a href="http://www.ietf.org/rfc/rfc2630.txt">
684: * </a></code> signature format as specified in RFC 2630.
685: * </p>
686: *
687: * @param stringToAuthenticate the string that is to be signed
688: * @param options the bitwise OR of the following options:
689: * <code>CMSMessageSignatureService.SIG_INCLUDE_CONTENT</code> and
690: * <code>CMSMessageSignatureService.SIG_INCLUDE_CERTIFICATE</code>.
691: * If the implementation
692: * does not support detached signatures
693: * (signatures without the original content),
694: * the absence of the
695: * <code>CMSMessageSignatureService.SIG_INCLUDE_CONTENT</code>
696: * option will result in a
697: * <code>CMSMessageSignatureServiceException</code> with a reason
698: * code of
699: * <code>CRYPTO_NO_DETACHED_SIG</code>. If the implementation
700: * does not support opaque signatures and the
701: * <code>CMSMessageSignatureService.SIG_INCLUDE_CONTENT</code>
702: * option is specified, a
703: * <code>CMSMessageSignatureServiceException</code>
704: * exception with a reason code of
705: * <code>CRYPTO_NO_OPAQUE_SIG</code> MUST be thrown. If
706: * certificate URIs are used instead of certificates and the
707: * <code>CMSMessageSignatureService.SIG_INCLUDE_CERTIFICATE</code>
708: * option is specified, a
709: * <code>CMSMessageSignatureServiceException</code> exception
710: * with a reason code of <code>CRYPTO_NO_CERTIFICATE</code>
711: * MUST be thrown.
712: *
713: * @param caNames an array of <code>String</code>s that
714: * contain the distinguished names of certification
715: * authorities that are trusted to issue certificates that
716: * may be used for authenticating a user.
717: * The distinguished name MUST be formatted according
718: * to <a href="http://www.ietf.org/rfc/rfc2253.txt">
719: * RFC 2253</a>. If this parameter is set to <code>null</code>
720: * or the array is empty,
721: * it is up to the implementation to interact with the user to
722: * select an appropriate certificate that may be used for
723: * authentication.
724: * If an entry in the <code>caNames</code> array is
725: * <code>null</code>, contains an empty String, or
726: * is not properly formatted according to RFC2253
727: * an <code>IllegalArgumentException</code>
728: * is thrown.
729: * If, for a given collection of <code>caNames</code> more than
730: * one certificate
731: * is available, a list of available certificates that are
732: * currently valid (i.e. not expired) MUST be displayed to the
733: * user for selection. The system clock MUST be used to determine
734: * the validity of certificates.
735: *
736: * @param securityElementPrompt guides a user to insert the
737: * correct security element
738: * if the security element is removable and not detected. If
739: * this parameter is set to <code>null</code> no information
740: * regarding which security element to use is displayed to
741: * the user.
742: * If there are no certificates that can be selected to
743: * complete the operation a
744: * <code>CMSMessageSignatureServiceException</code> is thrown
745: * and the <code>getReason</code> method
746: * MUST return the <code>CRYPTO_NO_CERTIFICATE</code>
747: * error code.
748: *
749: * @return the DER encoded signature, <code>null</code>
750: * if the signature generation was cancelled by the
751: * user before completion
752: * @throws CMSMessageSignatureServiceException if an
753: * error occurs during signature generation
754: * @throws IllegalArgumentException if the parameters are not
755: * valid
756: * @throws SecurityException if the caller is not
757: * authorized to generate authentication messages
758: * @throws UserCredentialManagerException if a security element
759: * is not found
760: */
761: public static final byte[] authenticate(
762: String stringToAuthenticate, int options, String[] caNames,
763: String securityElementPrompt)
764: throws CMSMessageSignatureServiceException,
765: UserCredentialManagerException {
766: /* Validate the options selected. */
767: checkOptions(options);
768:
769: return com.sun.satsa.pki.PKIManager.sign(
770: com.sun.satsa.pki.PKIManager.AUTHENTICATE_STRING, null,
771: stringToAuthenticate, options, caNames,
772: securityElementPrompt);
773: }
774:
775: /**
776: * Checks signing option word.
777: * @param options the bitwise OR of the following options:
778: * <code>CMSMessageSignatureService.SIG_INCLUDE_CONTENT</code> and
779: * <code>CMSMessageSignatureService.SIG_INCLUDE_CERTIFICATE</code>.
780: * If the implementation
781: * does not support detached signatures
782: * (signatures without the original content),
783: * the absence of the
784: * <code>CMSMessageSignatureService.SIG_INCLUDE_CONTENT</code>
785: * option will result in a
786: * <code>CMSMessageSignatureServiceException</code> with a reason
787: * code of
788: * <code>CRYPTO_NO_DETACHED_SIG</code>. If the implementation
789: * does not support opaque signatures and the
790: * <code>CMSMessageSignatureService.SIG_INCLUDE_CONTENT</code>
791: * option is specified, a
792: * <code>CMSMessageSignatureServiceException</code>
793: * exception with a reason code of
794: * <code>CRYPTO_NO_OPAQUE_SIG</code> MUST be thrown. If
795: * certificate URIs are used instead of certificates and the
796: * <code>CMSMessageSignatureService.SIG_INCLUDE_CERTIFICATE</code>
797: * option is specified, a
798: * <code>CMSMessageSignatureServiceException</code> exception
799: * with a reason code of <code>CRYPTO_NO_CERTIFICATE</code>
800: * MUST be thrown.
801: * @throws IllegalArgumentException if the <code>options</code>
802: * parameters are not valid
803: * @throws CMSMessageSignatureServiceException if an
804: * error occurs during signature generation
805: */
806: static void checkOptions(int options)
807: throws CMSMessageSignatureServiceException {
808: /* Check for valid arguments. */
809: if ((options & mask) != 0) {
810: throw new IllegalArgumentException(
811: "Invalid signing options ");
812: }
813:
814: if ((options & CMSMessageSignatureService.SIG_INCLUDE_CERTIFICATE) == CMSMessageSignatureService.SIG_INCLUDE_CERTIFICATE) {
815: if (!CMSMessageSignatureService.certSig) {
816: throw new CMSMessageSignatureServiceException(
817: CMSMessageSignatureServiceException.CRYPTO_NO_CERTIFICATE);
818: }
819: }
820: }
821: }
|