Source Code Cross Referenced for Signature.java in  » 6.0-JDK-Core » security » java » security » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Home
Java Source Code / Java Documentation
1.6.0 JDK Core
2.6.0 JDK Modules
3.6.0 JDK Modules com.sun
4.6.0 JDK Modules com.sun.java
5.6.0 JDK Modules sun
6.6.0 JDK Platform
7.Ajax
8.Apache Harmony Java SE
9.Aspect oriented
10.Authentication Authorization
11.Blogger System
12.Build
13.Byte Code
14.Cache
15.Chart
16.Chat
17.Code Analyzer
18.Collaboration
19.Content Management System
20.Database Client
21.Database DBMS
22.Database JDBC Connection Pool
23.Database ORM
24.Development
25.EJB Server
26.ERP CRM Financial
27.ESB
28.Forum
29.Game
30.GIS
31.Graphic 3D
32.Graphic Library
33.Groupware
34.HTML Parser
35.IDE
36.IDE Eclipse
37.IDE Netbeans
38.Installer
39.Internationalization Localization
40.Inversion of Control
41.Issue Tracking
42.J2EE
43.J2ME
44.JBoss
45.JMS
46.JMX
47.Library
48.Mail Clients
49.Music
50.Net
51.Parser
52.PDF
53.Portal
54.Profiler
55.Project Management
56.Report
57.RSS RDF
58.Rule Engine
59.Science
60.Scripting
61.Search Engine
62.Security
63.Sevlet Container
64.Source Control
65.Swing Library
66.Template Engine
67.Test Coverage
68.Testing
69.UML
70.Web Crawler
71.Web Framework
72.Web Mail
73.Web Server
74.Web Services
75.Web Services apache cxf 2.2.6
76.Web Services AXIS2
77.Wiki Engine
78.Workflow Engines
79.XML
80.XML UI
Java Source Code / Java Documentation » 6.0 JDK Core » security » java.security 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001        /*
0002         * Copyright 1996-2006 Sun Microsystems, Inc.  All Rights Reserved.
0003         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004         *
0005         * This code is free software; you can redistribute it and/or modify it
0006         * under the terms of the GNU General Public License version 2 only, as
0007         * published by the Free Software Foundation.  Sun designates this
0008         * particular file as subject to the "Classpath" exception as provided
0009         * by Sun in the LICENSE file that accompanied this code.
0010         *
0011         * This code is distributed in the hope that it will be useful, but WITHOUT
0012         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
0014         * version 2 for more details (a copy is included in the LICENSE file that
0015         * accompanied this code).
0016         *
0017         * You should have received a copy of the GNU General Public License version
0018         * 2 along with this work; if not, write to the Free Software Foundation,
0019         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020         *
0021         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022         * CA 95054 USA or visit www.sun.com if you need additional information or
0023         * have any questions.
0024         */
0025
0026        package java.security;
0027
0028        import java.security.spec.AlgorithmParameterSpec;
0029        import java.util.*;
0030        import java.util.concurrent.ConcurrentHashMap;
0031        import java.io.*;
0032        import java.security.cert.Certificate;
0033        import java.security.cert.X509Certificate;
0034
0035        import java.nio.ByteBuffer;
0036
0037        import java.security.Provider.Service;
0038
0039        import javax.crypto.Cipher;
0040        import javax.crypto.CipherSpi;
0041        import javax.crypto.IllegalBlockSizeException;
0042        import javax.crypto.BadPaddingException;
0043        import javax.crypto.NoSuchPaddingException;
0044
0045        import sun.security.util.Debug;
0046        import sun.security.jca.*;
0047        import sun.security.jca.GetInstance.Instance;
0048
0049        /**
0050         * This Signature class is used to provide applications the functionality
0051         * of a digital signature algorithm. Digital signatures are used for
0052         * authentication and integrity assurance of digital data.
0053         *
0054         * <p> The signature algorithm can be, among others, the NIST standard
0055         * DSA, using DSA and SHA-1. The DSA algorithm using the
0056         * SHA-1 message digest algorithm can be specified as <tt>SHA1withDSA</tt>.
0057         * In the case of RSA, there are multiple choices for the message digest
0058         * algorithm, so the signing algorithm could be specified as, for example,
0059         * <tt>MD2withRSA</tt>, <tt>MD5withRSA</tt>, or <tt>SHA1withRSA</tt>.
0060         * The algorithm name must be specified, as there is no default.
0061         *
0062         * <p> A Signature object can be used to generate and verify digital
0063         * signatures.
0064         *
0065         * <p> There are three phases to the use of a Signature object for
0066         * either signing data or verifying a signature:<ol>
0067         *
0068         * <li>Initialization, with either 
0069         *
0070         *     <ul>
0071         *
0072         *     <li>a public key, which initializes the signature for
0073         *     verification (see {@link #initVerify(PublicKey) initVerify}), or
0074         *
0075         *     <li>a private key (and optionally a Secure Random Number Generator),
0076         *     which initializes the signature for signing
0077         *     (see {@link #initSign(PrivateKey)}
0078         *     and {@link #initSign(PrivateKey, SecureRandom)}).
0079         *
0080         *     </ul><p>
0081         *
0082         * <li>Updating<p>
0083         *
0084         * <p>Depending on the type of initialization, this will update the
0085         * bytes to be signed or verified. See the 
0086         * {@link #update(byte) update} methods.<p>
0087         *
0088         * <li>Signing or Verifying a signature on all updated bytes. See the 
0089         * {@link #sign() sign} methods and the {@link #verify(byte[]) verify}
0090         * method.
0091         *
0092         * </ol>
0093         *
0094         * <p>Note that this class is abstract and extends from
0095         * <code>SignatureSpi</code> for historical reasons.
0096         * Application developers should only take notice of the methods defined in
0097         * this <code>Signature</code> class; all the methods in
0098         * the superclass are intended for cryptographic service providers who wish to
0099         * supply their own implementations of digital signature algorithms.
0100         *
0101         * @author Benjamin Renaud 
0102         *
0103         * @version 1.110, 05/05/07
0104         */
0105
0106        public abstract class Signature extends SignatureSpi {
0107
0108            private static final Debug debug = Debug.getInstance("jca",
0109                    "Signature");
0110
0111            /*
0112             * The algorithm for this signature object.
0113             * This value is used to map an OID to the particular algorithm.
0114             * The mapping is done in AlgorithmObject.algOID(String algorithm)
0115             */
0116            private String algorithm;
0117
0118            // The provider
0119            Provider provider;
0120
0121            /** 
0122             * Possible {@link #state} value, signifying that       
0123             * this signature object has not yet been initialized.
0124             */
0125            protected final static int UNINITIALIZED = 0;
0126
0127            /** 
0128             * Possible {@link #state} value, signifying that       
0129             * this signature object has been initialized for signing.
0130             */
0131            protected final static int SIGN = 2;
0132
0133            /** 
0134             * Possible {@link #state} value, signifying that       
0135             * this signature object has been initialized for verification.
0136             */
0137            protected final static int VERIFY = 3;
0138
0139            /** 
0140             * Current state of this signature object.
0141             */
0142            protected int state = UNINITIALIZED;
0143
0144            /**
0145             * Creates a Signature object for the specified algorithm.
0146             *
0147             * @param algorithm the standard string name of the algorithm. 
0148             * See Appendix A in the <a href=
0149             * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
0150             * Java Cryptography Architecture API Specification &amp; Reference </a> 
0151             * for information about standard algorithm names.
0152             */
0153            protected Signature(String algorithm) {
0154                this .algorithm = algorithm;
0155            }
0156
0157            // name of the special signature alg
0158            private final static String RSA_SIGNATURE = "NONEwithRSA";
0159
0160            // name of the equivalent cipher alg
0161            private final static String RSA_CIPHER = "RSA/ECB/PKCS1Padding";
0162
0163            // all the services we need to lookup for compatibility with Cipher
0164            private final static List<ServiceId> rsaIds = Arrays
0165                    .asList(new ServiceId[] {
0166                            new ServiceId("Signature", "NONEwithRSA"),
0167                            new ServiceId("Cipher", "RSA/ECB/PKCS1Padding"),
0168                            new ServiceId("Cipher", "RSA/ECB"),
0169                            new ServiceId("Cipher", "RSA//PKCS1Padding"),
0170                            new ServiceId("Cipher", "RSA"), });
0171
0172            /**
0173             * Returns a Signature object that implements the specified signature
0174             * algorithm.
0175             *
0176             * <p> This method traverses the list of registered security Providers,
0177             * starting with the most preferred Provider.
0178             * A new Signature object encapsulating the
0179             * SignatureSpi implementation from the first
0180             * Provider that supports the specified algorithm is returned.
0181             *
0182             * <p> Note that the list of registered providers may be retrieved via
0183             * the {@link Security#getProviders() Security.getProviders()} method.
0184             *
0185             * @param algorithm the standard name of the algorithm requested. 
0186             * See Appendix A in the <a href=
0187             * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
0188             * Java Cryptography Architecture API Specification &amp; Reference </a> 
0189             * for information about standard algorithm names.
0190             *
0191             * @return the new Signature object.
0192             *
0193             * @exception NoSuchAlgorithmException if no Provider supports a
0194             *          Signature implementation for the
0195             *          specified algorithm.
0196             *
0197             * @see Provider
0198             */
0199            public static Signature getInstance(String algorithm)
0200                    throws NoSuchAlgorithmException {
0201                List<Service> list;
0202                if (algorithm.equalsIgnoreCase(RSA_SIGNATURE)) {
0203                    list = GetInstance.getServices(rsaIds);
0204                } else {
0205                    list = GetInstance.getServices("Signature", algorithm);
0206                }
0207                Iterator<Service> t = list.iterator();
0208                if (t.hasNext() == false) {
0209                    throw new NoSuchAlgorithmException(algorithm
0210                            + " Signature not available");
0211                }
0212                // try services until we find an Spi or a working Signature subclass
0213                NoSuchAlgorithmException failure;
0214                do {
0215                    Service s = t.next();
0216                    if (isSpi(s)) {
0217                        return new Delegate(s, t, algorithm);
0218                    } else {
0219                        // must be a subclass of Signature, disable dynamic selection
0220                        try {
0221                            Instance instance = GetInstance.getInstance(s,
0222                                    SignatureSpi.class);
0223                            return getInstance(instance, algorithm);
0224                        } catch (NoSuchAlgorithmException e) {
0225                            failure = e;
0226                        }
0227                    }
0228                } while (t.hasNext());
0229                throw failure;
0230            }
0231
0232            private static Signature getInstance(Instance instance,
0233                    String algorithm) {
0234                Signature sig;
0235                if (instance.impl instanceof  Signature) {
0236                    sig = (Signature) instance.impl;
0237                } else {
0238                    SignatureSpi spi = (SignatureSpi) instance.impl;
0239                    sig = new Delegate(spi, algorithm);
0240                }
0241                sig.provider = instance.provider;
0242                return sig;
0243            }
0244
0245            private final static Map<String, Boolean> signatureInfo;
0246
0247            static {
0248                signatureInfo = new ConcurrentHashMap<String, Boolean>();
0249                Boolean TRUE = Boolean.TRUE;
0250                // pre-initialize with values for our SignatureSpi implementations
0251                signatureInfo.put("sun.security.provider.DSA$RawDSA", TRUE);
0252                signatureInfo
0253                        .put("sun.security.provider.DSA$SHA1withDSA", TRUE);
0254                signatureInfo.put("sun.security.rsa.RSASignature$MD2withRSA",
0255                        TRUE);
0256                signatureInfo.put("sun.security.rsa.RSASignature$MD5withRSA",
0257                        TRUE);
0258                signatureInfo.put("sun.security.rsa.RSASignature$SHA1withRSA",
0259                        TRUE);
0260                signatureInfo.put(
0261                        "sun.security.rsa.RSASignature$SHA256withRSA", TRUE);
0262                signatureInfo.put(
0263                        "sun.security.rsa.RSASignature$SHA384withRSA", TRUE);
0264                signatureInfo.put(
0265                        "sun.security.rsa.RSASignature$SHA512withRSA", TRUE);
0266                signatureInfo.put("com.sun.net.ssl.internal.ssl.RSASignature",
0267                        TRUE);
0268                signatureInfo.put("sun.security.pkcs11.P11Signature", TRUE);
0269            }
0270
0271            private static boolean isSpi(Service s) {
0272                if (s.getType().equals("Cipher")) {
0273                    // must be a CipherSpi, which we can wrap with the CipherAdapter
0274                    return true;
0275                }
0276                String className = s.getClassName();
0277                Boolean result = signatureInfo.get(className);
0278                if (result == null) {
0279                    try {
0280                        Object instance = s.newInstance(null);
0281                        // Signature extends SignatureSpi
0282                        // so it is a "real" Spi if it is an 
0283                        // instance of SignatureSpi but not Signature
0284                        boolean r = (instance instanceof  SignatureSpi)
0285                                && (instance instanceof  Signature == false);
0286                        if ((debug != null) && (r == false)) {
0287                            debug.println("Not a SignatureSpi " + className);
0288                            debug
0289                                    .println("Delayed provider selection may not be "
0290                                            + "available for algorithm "
0291                                            + s.getAlgorithm());
0292                        }
0293                        result = Boolean.valueOf(r);
0294                        signatureInfo.put(className, result);
0295                    } catch (Exception e) {
0296                        // something is wrong, assume not an SPI
0297                        return false;
0298                    }
0299                }
0300                return result.booleanValue();
0301            }
0302
0303            /** 
0304             * Returns a Signature object that implements the specified signature
0305             * algorithm.
0306             *
0307             * <p> A new Signature object encapsulating the
0308             * SignatureSpi implementation from the specified provider
0309             * is returned.  The specified provider must be registered
0310             * in the security provider list.
0311             *
0312             * <p> Note that the list of registered providers may be retrieved via
0313             * the {@link Security#getProviders() Security.getProviders()} method.
0314             *
0315             * @param algorithm the name of the algorithm requested.
0316             * See Appendix A in the <a href=
0317             * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
0318             * Java Cryptography Architecture API Specification &amp; Reference </a> 
0319             * for information about standard algorithm names.
0320             *
0321             * @param provider the name of the provider.
0322             *
0323             * @return the new Signature object.
0324             *
0325             * @exception NoSuchAlgorithmException if a SignatureSpi
0326             *		implementation for the specified algorithm is not
0327             *		available from the specified provider.
0328             *
0329             * @exception NoSuchProviderException if the specified provider is not
0330             *		registered in the security provider list.
0331             *
0332             * @exception IllegalArgumentException if the provider name is null
0333             *		or empty.
0334             * 
0335             * @see Provider 
0336             */
0337            public static Signature getInstance(String algorithm,
0338                    String provider) throws NoSuchAlgorithmException,
0339                    NoSuchProviderException {
0340                if (algorithm.equalsIgnoreCase(RSA_SIGNATURE)) {
0341                    // exception compatibility with existing code
0342                    if ((provider == null) || (provider.length() == 0)) {
0343                        throw new IllegalArgumentException("missing provider");
0344                    }
0345                    Provider p = Security.getProvider(provider);
0346                    if (p == null) {
0347                        throw new NoSuchProviderException("no such provider: "
0348                                + provider);
0349                    }
0350                    return getInstanceRSA(p);
0351                }
0352                Instance instance = GetInstance.getInstance("Signature",
0353                        SignatureSpi.class, algorithm, provider);
0354                return getInstance(instance, algorithm);
0355            }
0356
0357            /** 
0358             * Returns a Signature object that implements the specified
0359             * signature algorithm.
0360             *
0361             * <p> A new Signature object encapsulating the
0362             * SignatureSpi implementation from the specified Provider
0363             * object is returned.  Note that the specified Provider object
0364             * does not have to be registered in the provider list.
0365             *
0366             * @param algorithm the name of the algorithm requested.
0367             * See Appendix A in the <a href=
0368             * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
0369             * Java Cryptography Architecture API Specification &amp; Reference </a> 
0370             * for information about standard algorithm names.
0371             *
0372             * @param provider the provider.
0373             *
0374             * @return the new Signature object.
0375             *
0376             * @exception NoSuchAlgorithmException if a SignatureSpi
0377             *		implementation for the specified algorithm is not available
0378             *		from the specified Provider object.
0379             *
0380             * @exception IllegalArgumentException if the provider is null.
0381             * 
0382             * @see Provider
0383             *
0384             * @since 1.4
0385             */
0386            public static Signature getInstance(String algorithm,
0387                    Provider provider) throws NoSuchAlgorithmException {
0388                if (algorithm.equalsIgnoreCase(RSA_SIGNATURE)) {
0389                    // exception compatibility with existing code
0390                    if (provider == null) {
0391                        throw new IllegalArgumentException("missing provider");
0392                    }
0393                    return getInstanceRSA(provider);
0394                }
0395                Instance instance = GetInstance.getInstance("Signature",
0396                        SignatureSpi.class, algorithm, provider);
0397                return getInstance(instance, algorithm);
0398            }
0399
0400            // return an implementation for NONEwithRSA, which is a special case
0401            // because of the Cipher.RSA/ECB/PKCS1Padding compatibility wrapper
0402            private static Signature getInstanceRSA(Provider p)
0403                    throws NoSuchAlgorithmException {
0404                // try Signature first
0405                Service s = p.getService("Signature", RSA_SIGNATURE);
0406                if (s != null) {
0407                    Instance instance = GetInstance.getInstance(s,
0408                            SignatureSpi.class);
0409                    return getInstance(instance, RSA_SIGNATURE);
0410                }
0411                // check Cipher
0412                try {
0413                    Cipher c = Cipher.getInstance(RSA_CIPHER, p);
0414                    return new Delegate(new CipherAdapter(c), RSA_SIGNATURE);
0415                } catch (GeneralSecurityException e) {
0416                    // throw Signature style exception message to avoid confusion,
0417                    // but append Cipher exception as cause
0418                    throw new NoSuchAlgorithmException("no such algorithm: "
0419                            + RSA_SIGNATURE + " for provider " + p.getName(), e);
0420                }
0421            }
0422
0423            /** 
0424             * Returns the provider of this signature object.
0425             * 
0426             * @return the provider of this signature object
0427             */
0428            public final Provider getProvider() {
0429                chooseFirstProvider();
0430                return this .provider;
0431            }
0432
0433            void chooseFirstProvider() {
0434                // empty, overridden in Delegate
0435            }
0436
0437            /**
0438             * Initializes this object for verification. If this method is called
0439             * again with a different argument, it negates the effect
0440             * of this call.
0441             *
0442             * @param publicKey the public key of the identity whose signature is
0443             * going to be verified.
0444             *
0445             * @exception InvalidKeyException if the key is invalid.
0446             */
0447            public final void initVerify(PublicKey publicKey)
0448                    throws InvalidKeyException {
0449                engineInitVerify(publicKey);
0450                state = VERIFY;
0451            }
0452
0453            /**
0454             * Initializes this object for verification, using the public key from
0455             * the given certificate.
0456             * <p>If the certificate is of type X.509 and has a <i>key usage</i>
0457             * extension field marked as critical, and the value of the <i>key usage</i>
0458             * extension field implies that the public key in
0459             * the certificate and its corresponding private key are not
0460             * supposed to be used for digital signatures, an 
0461             * <code>InvalidKeyException</code> is thrown.
0462             *
0463             * @param certificate the certificate of the identity whose signature is
0464             * going to be verified.
0465             *
0466             * @exception InvalidKeyException  if the public key in the certificate
0467             * is not encoded properly or does not include required  parameter
0468             * information or cannot be used for digital signature purposes.
0469             * @since 1.3
0470             */
0471            public final void initVerify(Certificate certificate)
0472                    throws InvalidKeyException {
0473                // If the certificate is of type X509Certificate,
0474                // we should check whether it has a Key Usage
0475                // extension marked as critical.
0476                if (certificate instanceof  java.security.cert.X509Certificate) {
0477                    // Check whether the cert has a key usage extension
0478                    // marked as a critical extension.
0479                    // The OID for KeyUsage extension is 2.5.29.15.
0480                    X509Certificate cert = (X509Certificate) certificate;
0481                    Set<String> critSet = cert.getCriticalExtensionOIDs();
0482
0483                    if (critSet != null && !critSet.isEmpty()
0484                            && critSet.contains("2.5.29.15")) {
0485                        boolean[] keyUsageInfo = cert.getKeyUsage();
0486                        // keyUsageInfo[0] is for digitalSignature.
0487                        if ((keyUsageInfo != null)
0488                                && (keyUsageInfo[0] == false))
0489                            throw new InvalidKeyException("Wrong key usage");
0490                    }
0491                }
0492
0493                PublicKey publicKey = certificate.getPublicKey();
0494                engineInitVerify(publicKey);
0495                state = VERIFY;
0496            }
0497
0498            /**
0499             * Initialize this object for signing. If this method is called
0500             * again with a different argument, it negates the effect
0501             * of this call.
0502             *
0503             * @param privateKey the private key of the identity whose signature
0504             * is going to be generated.
0505             * 
0506             * @exception InvalidKeyException if the key is invalid.  
0507             */
0508            public final void initSign(PrivateKey privateKey)
0509                    throws InvalidKeyException {
0510                engineInitSign(privateKey);
0511                state = SIGN;
0512            }
0513
0514            /**
0515             * Initialize this object for signing. If this method is called
0516             * again with a different argument, it negates the effect
0517             * of this call.
0518             *
0519             * @param privateKey the private key of the identity whose signature
0520             * is going to be generated.
0521             * 
0522             * @param random the source of randomness for this signature.
0523             * 
0524             * @exception InvalidKeyException if the key is invalid.  
0525             */
0526            public final void initSign(PrivateKey privateKey,
0527                    SecureRandom random) throws InvalidKeyException {
0528                engineInitSign(privateKey, random);
0529                state = SIGN;
0530            }
0531
0532            /**
0533             * Returns the signature bytes of all the data updated.
0534             * The format of the signature depends on the underlying 
0535             * signature scheme.
0536             * 
0537             * <p>A call to this method resets this signature object to the state 
0538             * it was in when previously initialized for signing via a
0539             * call to <code>initSign(PrivateKey)</code>. That is, the object is 
0540             * reset and available to generate another signature from the same 
0541             * signer, if desired, via new calls to <code>update</code> and 
0542             * <code>sign</code>.     
0543             *
0544             * @return the signature bytes of the signing operation's result.
0545             *
0546             * @exception SignatureException if this signature object is not
0547             * initialized properly or if this signature algorithm is unable to
0548             * process the input data provided.
0549             */
0550            public final byte[] sign() throws SignatureException {
0551                if (state == SIGN) {
0552                    return engineSign();
0553                }
0554                throw new SignatureException("object not initialized for "
0555                        + "signing");
0556            }
0557
0558            /**
0559             * Finishes the signature operation and stores the resulting signature
0560             * bytes in the provided buffer <code>outbuf</code>, starting at
0561             * <code>offset</code>. 
0562             * The format of the signature depends on the underlying 
0563             * signature scheme.
0564             * 
0565             * <p>This signature object is reset to its initial state (the state it
0566             * was in after a call to one of the <code>initSign</code> methods) and
0567             * can be reused to generate further signatures with the same private key.
0568             *
0569             * @param outbuf buffer for the signature result.
0570             *
0571             * @param offset offset into <code>outbuf</code> where the signature is
0572             * stored.
0573             *
0574             * @param len number of bytes within <code>outbuf</code> allotted for the
0575             * signature.
0576             *
0577             * @return the number of bytes placed into <code>outbuf</code>.
0578             *
0579             * @exception SignatureException if this signature object is not
0580             * initialized properly, if this signature algorithm is unable to
0581             * process the input data provided, or if <code>len</code> is less
0582             * than the actual signature length.
0583             *
0584             * @since 1.2
0585             */
0586            public final int sign(byte[] outbuf, int offset, int len)
0587                    throws SignatureException {
0588                if (outbuf == null) {
0589                    throw new IllegalArgumentException("No output buffer given");
0590                }
0591                if (outbuf.length - offset < len) {
0592                    throw new IllegalArgumentException(
0593                            "Output buffer too small for specified offset and length");
0594                }
0595                if (state != SIGN) {
0596                    throw new SignatureException("object not initialized for "
0597                            + "signing");
0598                }
0599                return engineSign(outbuf, offset, len);
0600            }
0601
0602            /**
0603             * Verifies the passed-in signature. 
0604             * 
0605             * <p>A call to this method resets this signature object to the state 
0606             * it was in when previously initialized for verification via a
0607             * call to <code>initVerify(PublicKey)</code>. That is, the object is 
0608             * reset and available to verify another signature from the identity
0609             * whose public key was specified in the call to <code>initVerify</code>.
0610             *      
0611             * @param signature the signature bytes to be verified.
0612             *
0613             * @return true if the signature was verified, false if not. 
0614             *
0615             * @exception SignatureException if this signature object is not 
0616             * initialized properly, the passed-in signature is improperly 
0617             * encoded or of the wrong type, if this signature algorithm is unable to
0618             * process the input data provided, etc.
0619             */
0620            public final boolean verify(byte[] signature)
0621                    throws SignatureException {
0622                if (state == VERIFY) {
0623                    return engineVerify(signature);
0624                }
0625                throw new SignatureException("object not initialized for "
0626                        + "verification");
0627            }
0628
0629            /**
0630             * Verifies the passed-in signature in the specified array
0631             * of bytes, starting at the specified offset.
0632             * 
0633             * <p>A call to this method resets this signature object to the state 
0634             * it was in when previously initialized for verification via a
0635             * call to <code>initVerify(PublicKey)</code>. That is, the object is 
0636             * reset and available to verify another signature from the identity
0637             * whose public key was specified in the call to <code>initVerify</code>.
0638             *
0639             *      
0640             * @param signature the signature bytes to be verified.
0641             * @param offset the offset to start from in the array of bytes.
0642             * @param length the number of bytes to use, starting at offset.
0643             *
0644             * @return true if the signature was verified, false if not. 
0645             *
0646             * @exception SignatureException if this signature object is not 
0647             * initialized properly, the passed-in signature is improperly 
0648             * encoded or of the wrong type, if this signature algorithm is unable to
0649             * process the input data provided, etc.
0650             * @exception IllegalArgumentException if the <code>signature</code>
0651             * byte array is null, or the <code>offset</code> or <code>length</code>
0652             * is less than 0, or the sum of the <code>offset</code> and 
0653             * <code>length</code> is greater than the length of the
0654             * <code>signature</code> byte array.
0655             * @since 1.4
0656             */
0657            public final boolean verify(byte[] signature, int offset, int length)
0658                    throws SignatureException {
0659                if (state == VERIFY) {
0660                    if ((signature == null) || (offset < 0) || (length < 0)
0661                            || (offset + length > signature.length)) {
0662                        throw new IllegalArgumentException("Bad arguments");
0663                    }
0664
0665                    return engineVerify(signature, offset, length);
0666                }
0667                throw new SignatureException("object not initialized for "
0668                        + "verification");
0669            }
0670
0671            /**
0672             * Updates the data to be signed or verified by a byte.
0673             *
0674             * @param b the byte to use for the update.
0675             * 
0676             * @exception SignatureException if this signature object is not 
0677             * initialized properly.     
0678             */
0679            public final void update(byte b) throws SignatureException {
0680                if (state == VERIFY || state == SIGN) {
0681                    engineUpdate(b);
0682                } else {
0683                    throw new SignatureException("object not initialized for "
0684                            + "signature or verification");
0685                }
0686            }
0687
0688            /**
0689             * Updates the data to be signed or verified, using the specified
0690             * array of bytes.
0691             *
0692             * @param data the byte array to use for the update.       
0693             * 
0694             * @exception SignatureException if this signature object is not 
0695             * initialized properly.          
0696             */
0697            public final void update(byte[] data) throws SignatureException {
0698                update(data, 0, data.length);
0699            }
0700
0701            /**
0702             * Updates the data to be signed or verified, using the specified
0703             * array of bytes, starting at the specified offset.  
0704             *
0705             * @param data the array of bytes.  
0706             * @param off the offset to start from in the array of bytes.  
0707             * @param len the number of bytes to use, starting at offset.
0708             *  
0709             * @exception SignatureException if this signature object is not 
0710             * initialized properly.          
0711             */
0712            public final void update(byte[] data, int off, int len)
0713                    throws SignatureException {
0714                if (state == SIGN || state == VERIFY) {
0715                    engineUpdate(data, off, len);
0716                } else {
0717                    throw new SignatureException("object not initialized for "
0718                            + "signature or verification");
0719                }
0720            }
0721
0722            /**
0723             * Updates the data to be signed or verified using the specified
0724             * ByteBuffer. Processes the <code>data.remaining()</code> bytes
0725             * starting at at <code>data.position()</code>.
0726             * Upon return, the buffer's position will be equal to its limit;
0727             * its limit will not have changed.
0728             *
0729             * @param data the ByteBuffer
0730             *
0731             * @exception SignatureException if this signature object is not
0732             * initialized properly.
0733             * @since 1.5
0734             */
0735            public final void update(ByteBuffer data) throws SignatureException {
0736                if ((state != SIGN) && (state != VERIFY)) {
0737                    throw new SignatureException("object not initialized for "
0738                            + "signature or verification");
0739                }
0740                if (data == null) {
0741                    throw new NullPointerException();
0742                }
0743                engineUpdate(data);
0744            }
0745
0746            /** 
0747             * Returns the name of the algorithm for this signature object.
0748             * 
0749             * @return the name of the algorithm for this signature object.
0750             */
0751            public final String getAlgorithm() {
0752                return this .algorithm;
0753            }
0754
0755            /**
0756             * Returns a string representation of this signature object,       
0757             * providing information that includes the state of the object       
0758             * and the name of the algorithm used.       
0759             * 
0760             * @return a string representation of this signature object.
0761             */
0762            public String toString() {
0763                String initState = "";
0764                switch (state) {
0765                case UNINITIALIZED:
0766                    initState = "<not initialized>";
0767                    break;
0768                case VERIFY:
0769                    initState = "<initialized for verifying>";
0770                    break;
0771                case SIGN:
0772                    initState = "<initialized for signing>";
0773                    break;
0774                }
0775                return "Signature object: " + getAlgorithm() + initState;
0776            }
0777
0778            /**
0779             * Sets the specified algorithm parameter to the specified value.
0780             * This method supplies a general-purpose mechanism through
0781             * which it is possible to set the various parameters of this object. 
0782             * A parameter may be any settable parameter for the algorithm, such as 
0783             * a parameter size, or a source of random bits for signature generation 
0784             * (if appropriate), or an indication of whether or not to perform
0785             * a specific but optional computation. A uniform algorithm-specific 
0786             * naming scheme for each parameter is desirable but left unspecified 
0787             * at this time.
0788             *
0789             * @param param the string identifier of the parameter.
0790             * @param value the parameter value.
0791             *
0792             * @exception InvalidParameterException if <code>param</code> is an
0793             * invalid parameter for this signature algorithm engine,
0794             * the parameter is already set
0795             * and cannot be set again, a security exception occurs, and so on.
0796             *
0797             * @see #getParameter
0798             *
0799             * @deprecated Use 
0800             * {@link #setParameter(java.security.spec.AlgorithmParameterSpec)
0801             * setParameter}.
0802             */
0803            @Deprecated
0804            public final void setParameter(String param, Object value)
0805                    throws InvalidParameterException {
0806                engineSetParameter(param, value);
0807            }
0808
0809            /**
0810             * Initializes this signature engine with the specified parameter set.
0811             *
0812             * @param params the parameters
0813             *
0814             * @exception InvalidAlgorithmParameterException if the given parameters
0815             * are inappropriate for this signature engine
0816             *
0817             * @see #getParameters
0818             */
0819            public final void setParameter(AlgorithmParameterSpec params)
0820                    throws InvalidAlgorithmParameterException {
0821                engineSetParameter(params);
0822            }
0823
0824            /**
0825             * Returns the parameters used with this signature object.
0826             *
0827             * <p>The returned parameters may be the same that were used to initialize
0828             * this signature, or may contain a combination of default and randomly
0829             * generated parameter values used by the underlying signature 
0830             * implementation if this signature requires algorithm parameters but 
0831             * was not initialized with any.
0832             *
0833             * @return the parameters used with this signature, or null if this
0834             * signature does not use any parameters.
0835             *
0836             * @see #setParameter(AlgorithmParameterSpec)
0837             * @since 1.4
0838             */
0839            public final AlgorithmParameters getParameters() {
0840                return engineGetParameters();
0841            }
0842
0843            /**
0844             * Gets the value of the specified algorithm parameter. This method 
0845             * supplies a general-purpose mechanism through which it is possible to 
0846             * get the various parameters of this object. A parameter may be any 
0847             * settable parameter for the algorithm, such as a parameter size, or 
0848             * a source of random bits for signature generation (if appropriate), 
0849             * or an indication of whether or not to perform a specific but optional 
0850             * computation. A uniform algorithm-specific naming scheme for each 
0851             * parameter is desirable but left unspecified at this time.
0852             *
0853             * @param param the string name of the parameter.
0854             *
0855             * @return the object that represents the parameter value, or null if
0856             * there is none.
0857             *
0858             * @exception InvalidParameterException if <code>param</code> is an invalid
0859             * parameter for this engine, or another exception occurs while
0860             * trying to get this parameter.
0861             *
0862             * @see #setParameter(String, Object)
0863             *
0864             * @deprecated
0865             */
0866            @Deprecated
0867            public final Object getParameter(String param)
0868                    throws InvalidParameterException {
0869                return engineGetParameter(param);
0870            }
0871
0872            /**
0873             * Returns a clone if the implementation is cloneable.
0874             * 
0875             * @return a clone if the implementation is cloneable.
0876             *
0877             * @exception CloneNotSupportedException if this is called
0878             * on an implementation that does not support <code>Cloneable</code>.
0879             */
0880            public Object clone() throws CloneNotSupportedException {
0881                if (this  instanceof  Cloneable) {
0882                    return super .clone();
0883                } else {
0884                    throw new CloneNotSupportedException();
0885                }
0886            }
0887
0888            /*
0889             * The following class allows providers to extend from SignatureSpi
0890             * rather than from Signature. It represents a Signature with an
0891             * encapsulated, provider-supplied SPI object (of type SignatureSpi).
0892             * If the provider implementation is an instance of SignatureSpi, the
0893             * getInstance() methods above return an instance of this class, with
0894             * the SPI object encapsulated.
0895             *
0896             * Note: All SPI methods from the original Signature class have been
0897             * moved up the hierarchy into a new class (SignatureSpi), which has
0898             * been interposed in the hierarchy between the API (Signature)
0899             * and its original parent (Object).
0900             */
0901
0902            private static class Delegate extends Signature {
0903
0904                // The provider implementation (delegate)
0905                // filled in once the provider is selected
0906                private SignatureSpi sigSpi;
0907
0908                // lock for mutex during provider selection
0909                private final Object lock;
0910
0911                // next service to try in provider selection
0912                // null once provider is selected
0913                private Service firstService;
0914
0915                // remaining services to try in provider selection
0916                // null once provider is selected
0917                private Iterator<Service> serviceIterator;
0918
0919                // constructor
0920                Delegate(SignatureSpi sigSpi, String algorithm) {
0921                    super (algorithm);
0922                    this .sigSpi = sigSpi;
0923                    this .lock = null; // no lock needed
0924                }
0925
0926                // used with delayed provider selection
0927                Delegate(Service service, Iterator<Service> iterator,
0928                        String algorithm) {
0929                    super (algorithm);
0930                    this .firstService = service;
0931                    this .serviceIterator = iterator;
0932                    this .lock = new Object();
0933                }
0934
0935                /**
0936                 * Returns a clone if the delegate is cloneable.    
0937                 * 
0938                 * @return a clone if the delegate is cloneable.
0939                 *
0940                 * @exception CloneNotSupportedException if this is called on a
0941                 * delegate that does not support <code>Cloneable</code>.
0942                 */
0943                public Object clone() throws CloneNotSupportedException {
0944                    chooseFirstProvider();
0945                    if (sigSpi instanceof  Cloneable) {
0946                        SignatureSpi sigSpiClone = (SignatureSpi) sigSpi
0947                                .clone();
0948                        // Because 'algorithm' and 'provider' are private
0949                        // members of our supertype, we must perform a cast to
0950                        // access them.
0951                        Signature that = new Delegate(sigSpiClone,
0952                                ((Signature) this ).algorithm);
0953                        that.provider = ((Signature) this ).provider;
0954                        return that;
0955                    } else {
0956                        throw new CloneNotSupportedException();
0957                    }
0958                }
0959
0960                private static SignatureSpi newInstance(Service s)
0961                        throws NoSuchAlgorithmException {
0962                    if (s.getType().equals("Cipher")) {
0963                        // must be NONEwithRSA
0964                        try {
0965                            Cipher c = Cipher.getInstance(RSA_CIPHER, s
0966                                    .getProvider());
0967                            return new CipherAdapter(c);
0968                        } catch (NoSuchPaddingException e) {
0969                            throw new NoSuchAlgorithmException(e);
0970                        }
0971                    } else {
0972                        Object o = s.newInstance(null);
0973                        if (o instanceof  SignatureSpi == false) {
0974                            throw new NoSuchAlgorithmException(
0975                                    "Not a SignatureSpi: "
0976                                            + o.getClass().getName());
0977                        }
0978                        return (SignatureSpi) o;
0979                    }
0980                }
0981
0982                // max number of debug warnings to print from chooseFirstProvider()
0983                private static int warnCount = 10;
0984
0985                /**
0986                 * Choose the Spi from the first provider available. Used if
0987                 * delayed provider selection is not possible because initSign()/
0988                 * initVerify() is not the first method called.
0989                 */
0990                void chooseFirstProvider() {
0991                    if (sigSpi != null) {
0992                        return;
0993                    }
0994                    synchronized (lock) {
0995                        if (sigSpi != null) {
0996                            return;
0997                        }
0998                        if (debug != null) {
0999                            int w = --warnCount;
1000                            if (w >= 0) {
1001                                debug
1002                                        .println("Signature.init() not first method "
1003                                                + "called, disabling delayed provider selection");
1004                                if (w == 0) {
1005                                    debug
1006                                            .println("Further warnings of this type will "
1007                                                    + "be suppressed");
1008                                }
1009                                new Exception("Call trace").printStackTrace();
1010                            }
1011                        }
1012                        Exception lastException = null;
1013                        while ((firstService != null)
1014                                || serviceIterator.hasNext()) {
1015                            Service s;
1016                            if (firstService != null) {
1017                                s = firstService;
1018                                firstService = null;
1019                            } else {
1020                                s = serviceIterator.next();
1021                            }
1022                            if (isSpi(s) == false) {
1023                                continue;
1024                            }
1025                            try {
1026                                sigSpi = newInstance(s);
1027                                provider = s.getProvider();
1028                                // not needed any more
1029                                firstService = null;
1030                                serviceIterator = null;
1031                                return;
1032                            } catch (NoSuchAlgorithmException e) {
1033                                lastException = e;
1034                            }
1035                        }
1036                        ProviderException e = new ProviderException(
1037                                "Could not construct SignatureSpi instance");
1038                        if (lastException != null) {
1039                            e.initCause(lastException);
1040                        }
1041                        throw e;
1042                    }
1043                }
1044
1045                private void chooseProvider(int type, Key key,
1046                        SecureRandom random) throws InvalidKeyException {
1047                    synchronized (lock) {
1048                        if (sigSpi != null) {
1049                            init(sigSpi, type, key, random);
1050                            return;
1051                        }
1052                        Exception lastException = null;
1053                        while ((firstService != null)
1054                                || serviceIterator.hasNext()) {
1055                            Service s;
1056                            if (firstService != null) {
1057                                s = firstService;
1058                                firstService = null;
1059                            } else {
1060                                s = serviceIterator.next();
1061                            }
1062                            // if provider says it does not support this key, ignore it
1063                            if (s.supportsParameter(key) == false) {
1064                                continue;
1065                            }
1066                            // if instance is not a SignatureSpi, ignore it
1067                            if (isSpi(s) == false) {
1068                                continue;
1069                            }
1070                            try {
1071                                SignatureSpi spi = newInstance(s);
1072                                init(spi, type, key, random);
1073                                provider = s.getProvider();
1074                                sigSpi = spi;
1075                                firstService = null;
1076                                serviceIterator = null;
1077                                return;
1078                            } catch (Exception e) {
1079                                // NoSuchAlgorithmException from newInstance()
1080                                // InvalidKeyException from init()
1081                                // RuntimeException (ProviderException) from init()
1082                                if (lastException == null) {
1083                                    lastException = e;
1084                                }
1085                            }
1086                        }
1087                        // no working provider found, fail
1088                        if (lastException instanceof  InvalidKeyException) {
1089                            throw (InvalidKeyException) lastException;
1090                        }
1091                        if (lastException instanceof  RuntimeException) {
1092                            throw (RuntimeException) lastException;
1093                        }
1094                        String k = (key != null) ? key.getClass().getName()
1095                                : "(null)";
1096                        throw new InvalidKeyException(
1097                                "No installed provider supports this key: " + k,
1098                                lastException);
1099                    }
1100                }
1101
1102                private final static int I_PUB = 1;
1103                private final static int I_PRIV = 2;
1104                private final static int I_PRIV_SR = 3;
1105
1106                private void init(SignatureSpi spi, int type, Key key,
1107                        SecureRandom random) throws InvalidKeyException {
1108                    switch (type) {
1109                    case I_PUB:
1110                        spi.engineInitVerify((PublicKey) key);
1111                        break;
1112                    case I_PRIV:
1113                        spi.engineInitSign((PrivateKey) key);
1114                        break;
1115                    case I_PRIV_SR:
1116                        spi.engineInitSign((PrivateKey) key, random);
1117                        break;
1118                    default:
1119                        throw new AssertionError("Internal error: " + type);
1120                    }
1121                }
1122
1123                protected void engineInitVerify(PublicKey publicKey)
1124                        throws InvalidKeyException {
1125                    if (sigSpi != null) {
1126                        sigSpi.engineInitVerify(publicKey);
1127                    } else {
1128                        chooseProvider(I_PUB, publicKey, null);
1129                    }
1130                }
1131
1132                protected void engineInitSign(PrivateKey privateKey)
1133                        throws InvalidKeyException {
1134                    if (sigSpi != null) {
1135                        sigSpi.engineInitSign(privateKey);
1136                    } else {
1137                        chooseProvider(I_PRIV, privateKey, null);
1138                    }
1139                }
1140
1141                protected void engineInitSign(PrivateKey privateKey,
1142                        SecureRandom sr) throws InvalidKeyException {
1143                    if (sigSpi != null) {
1144                        sigSpi.engineInitSign(privateKey, sr);
1145                    } else {
1146                        chooseProvider(I_PRIV_SR, privateKey, sr);
1147                    }
1148                }
1149
1150                protected void engineUpdate(byte b) throws SignatureException {
1151                    chooseFirstProvider();
1152                    sigSpi.engineUpdate(b);
1153                }
1154
1155                protected void engineUpdate(byte[] b, int off, int len)
1156                        throws SignatureException {
1157                    chooseFirstProvider();
1158                    sigSpi.engineUpdate(b, off, len);
1159                }
1160
1161                protected void engineUpdate(ByteBuffer data) {
1162                    chooseFirstProvider();
1163                    sigSpi.engineUpdate(data);
1164                }
1165
1166                protected byte[] engineSign() throws SignatureException {
1167                    chooseFirstProvider();
1168                    return sigSpi.engineSign();
1169                }
1170
1171                protected int engineSign(byte[] outbuf, int offset, int len)
1172                        throws SignatureException {
1173                    chooseFirstProvider();
1174                    return sigSpi.engineSign(outbuf, offset, len);
1175                }
1176
1177                protected boolean engineVerify(byte[] sigBytes)
1178                        throws SignatureException {
1179                    chooseFirstProvider();
1180                    return sigSpi.engineVerify(sigBytes);
1181                }
1182
1183                protected boolean engineVerify(byte[] sigBytes, int offset,
1184                        int length) throws SignatureException {
1185                    chooseFirstProvider();
1186                    return sigSpi.engineVerify(sigBytes, offset, length);
1187                }
1188
1189                protected void engineSetParameter(String param, Object value)
1190                        throws InvalidParameterException {
1191                    chooseFirstProvider();
1192                    sigSpi.engineSetParameter(param, value);
1193                }
1194
1195                protected void engineSetParameter(AlgorithmParameterSpec params)
1196                        throws InvalidAlgorithmParameterException {
1197                    chooseFirstProvider();
1198                    sigSpi.engineSetParameter(params);
1199                }
1200
1201                protected Object engineGetParameter(String param)
1202                        throws InvalidParameterException {
1203                    chooseFirstProvider();
1204                    return sigSpi.engineGetParameter(param);
1205                }
1206
1207                protected AlgorithmParameters engineGetParameters() {
1208                    chooseFirstProvider();
1209                    return sigSpi.engineGetParameters();
1210                }
1211            }
1212
1213            // adapter for RSA/ECB/PKCS1Padding ciphers
1214            private static class CipherAdapter extends SignatureSpi {
1215
1216                private final Cipher cipher;
1217
1218                private ByteArrayOutputStream data;
1219
1220                CipherAdapter(Cipher cipher) {
1221                    this .cipher = cipher;
1222                }
1223
1224                protected void engineInitVerify(PublicKey publicKey)
1225                        throws InvalidKeyException {
1226                    cipher.init(Cipher.DECRYPT_MODE, publicKey);
1227                    if (data == null) {
1228                        data = new ByteArrayOutputStream(128);
1229                    } else {
1230                        data.reset();
1231                    }
1232                }
1233
1234                protected void engineInitSign(PrivateKey privateKey)
1235                        throws InvalidKeyException {
1236                    cipher.init(Cipher.ENCRYPT_MODE, privateKey);
1237                    data = null;
1238                }
1239
1240                protected void engineInitSign(PrivateKey privateKey,
1241                        SecureRandom random) throws InvalidKeyException {
1242                    cipher.init(Cipher.ENCRYPT_MODE, privateKey, random);
1243                    data = null;
1244                }
1245
1246                protected void engineUpdate(byte b) throws SignatureException {
1247                    engineUpdate(new byte[] { b }, 0, 1);
1248                }
1249
1250                protected void engineUpdate(byte[] b, int off, int len)
1251                        throws SignatureException {
1252                    if (data != null) {
1253                        data.write(b, off, len);
1254                        return;
1255                    }
1256                    byte[] out = cipher.update(b, off, len);
1257                    if ((out != null) && (out.length != 0)) {
1258                        throw new SignatureException(
1259                                "Cipher unexpectedly returned data");
1260                    }
1261                }
1262
1263                protected byte[] engineSign() throws SignatureException {
1264                    try {
1265                        return cipher.doFinal();
1266                    } catch (IllegalBlockSizeException e) {
1267                        throw new SignatureException("doFinal() failed", e);
1268                    } catch (BadPaddingException e) {
1269                        throw new SignatureException("doFinal() failed", e);
1270                    }
1271                }
1272
1273                protected boolean engineVerify(byte[] sigBytes)
1274                        throws SignatureException {
1275                    try {
1276                        byte[] out = cipher.doFinal(sigBytes);
1277                        byte[] dataBytes = data.toByteArray();
1278                        data.reset();
1279                        return Arrays.equals(out, dataBytes);
1280                    } catch (BadPaddingException e) {
1281                        // e.g. wrong public key used
1282                        // return false rather than throwing exception
1283                        return false;
1284                    } catch (IllegalBlockSizeException e) {
1285                        throw new SignatureException("doFinal() failed", e);
1286                    }
1287                }
1288
1289                protected void engineSetParameter(String param, Object value)
1290                        throws InvalidParameterException {
1291                    throw new InvalidParameterException(
1292                            "Parameters not supported");
1293                }
1294
1295                protected Object engineGetParameter(String param)
1296                        throws InvalidParameterException {
1297                    throw new InvalidParameterException(
1298                            "Parameters not supported");
1299                }
1300
1301            }
1302
1303        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.