Home | History | Annotate | Download | only in security
      1 /*
      2  * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
      3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      4  *
      5  * This code is free software; you can redistribute it and/or modify it
      6  * under the terms of the GNU General Public License version 2 only, as
      7  * published by the Free Software Foundation.  Oracle designates this
      8  * particular file as subject to the "Classpath" exception as provided
      9  * by Oracle in the LICENSE file that accompanied this code.
     10  *
     11  * This code is distributed in the hope that it will be useful, but WITHOUT
     12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     14  * version 2 for more details (a copy is included in the LICENSE file that
     15  * accompanied this code).
     16  *
     17  * You should have received a copy of the GNU General Public License version
     18  * 2 along with this work; if not, write to the Free Software Foundation,
     19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
     20  *
     21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
     22  * or visit www.oracle.com if you need additional information or have any
     23  * questions.
     24  */
     25 
     26 package java.security;
     27 
     28 import java.util.*;
     29 import java.lang.*;
     30 import java.io.IOException;
     31 import java.io.ByteArrayOutputStream;
     32 import java.io.PrintStream;
     33 import java.io.InputStream;
     34 import java.io.ByteArrayInputStream;
     35 
     36 import java.nio.ByteBuffer;
     37 
     38 import sun.security.jca.Providers;
     39 
     40 /**
     41  * This MessageDigest class provides applications the functionality of a
     42  * message digest algorithm, such as SHA-1 or SHA-256.
     43  * Message digests are secure one-way hash functions that take arbitrary-sized
     44  * data and output a fixed-length hash value.
     45  *
     46  * <p>A MessageDigest object starts out initialized. The data is
     47  * processed through it using the {@link #update(byte) update}
     48  * methods. At any point {@link #reset() reset} can be called
     49  * to reset the digest. Once all the data to be updated has been
     50  * updated, one of the {@link #digest() digest} methods should
     51  * be called to complete the hash computation.
     52  *
     53  * <p>The {@code digest} method can be called once for a given number
     54  * of updates. After {@code digest} has been called, the MessageDigest
     55  * object is reset to its initialized state.
     56  *
     57  * <p>Implementations are free to implement the Cloneable interface.
     58  * Client applications can test cloneability by attempting cloning
     59  * and catching the CloneNotSupportedException:
     60  *
     61  * <pre>{@code
     62  * MessageDigest md = MessageDigest.getInstance("SHA");
     63  *
     64  * try {
     65  *     md.update(toChapter1);
     66  *     MessageDigest tc1 = md.clone();
     67  *     byte[] toChapter1Digest = tc1.digest();
     68  *     md.update(toChapter2);
     69  *     ...etc.
     70  * } catch (CloneNotSupportedException cnse) {
     71  *     throw new DigestException("couldn't make digest of partial content");
     72  * }
     73  * }</pre>
     74  *
     75  * <p>Note that if a given implementation is not cloneable, it is
     76  * still possible to compute intermediate digests by instantiating
     77  * several instances, if the number of digests is known in advance.
     78  *
     79  * <p>Note that this class is abstract and extends from
     80  * {@code MessageDigestSpi} for historical reasons.
     81  * Application developers should only take notice of the methods defined in
     82  * this {@code MessageDigest} class; all the methods in
     83  * the superclass are intended for cryptographic service providers who wish to
     84  * supply their own implementations of message digest algorithms.
     85  *
     86  * <p> Android provides the following <code>MessageDigest</code> algorithms:
     87  * <table>
     88  *   <thead>
     89  *     <tr>
     90  *       <th>Algorithm</th>
     91  *       <th>Supported API Levels</th>
     92  *     </tr>
     93  *   </thead>
     94  *   <tbody>
     95  *     <tr>
     96  *       <td>MD5</td>
     97  *       <td>1+</td>
     98  *     </tr>
     99  *     <tr>
    100  *       <td>SHA-1</td>
    101  *       <td>1+</td>
    102  *     </tr>
    103  *     <tr>
    104  *       <td>SHA-224</td>
    105  *       <td>1-8,22+</td>
    106  *     </tr>
    107  *     <tr>
    108  *       <td>SHA-256</td>
    109  *       <td>1+</td>
    110  *     </tr>
    111  *     <tr>
    112  *       <td>SHA-384</td>
    113  *       <td>1+</td>
    114  *     </tr>
    115  *     <tr>
    116  *       <td>SHA-512</td>
    117  *       <td>1+</td>
    118  *     </tr>
    119  *   </tbody>
    120  * </table>
    121  *
    122  * These algorithms are described in the <a href=
    123  * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#MessageDigest">
    124  * MessageDigest section</a> of the
    125  * Java Cryptography Architecture Standard Algorithm Name Documentation.
    126  *
    127  * @author Benjamin Renaud
    128  *
    129  * @see DigestInputStream
    130  * @see DigestOutputStream
    131  */
    132 
    133 public abstract class MessageDigest extends MessageDigestSpi {
    134 
    135     // Android-removed: this debugging mechanism is not used in Android.
    136     /*
    137     private static final Debug pdebug =
    138                         Debug.getInstance("provider", "Provider");
    139     private static final boolean skipDebug =
    140         Debug.isOn("engine=") && !Debug.isOn("messagedigest");
    141     */
    142 
    143     private String algorithm;
    144 
    145     // The state of this digest
    146     private static final int INITIAL = 0;
    147     private static final int IN_PROGRESS = 1;
    148     private int state = INITIAL;
    149 
    150     // The provider
    151     private Provider provider;
    152 
    153     /**
    154      * Creates a message digest with the specified algorithm name.
    155      *
    156      * @param algorithm the standard name of the digest algorithm.
    157      * See the MessageDigest section in the <a href=
    158      * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#MessageDigest">
    159      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
    160      * for information about standard algorithm names.
    161      */
    162     protected MessageDigest(String algorithm) {
    163         this.algorithm = algorithm;
    164     }
    165 
    166     /**
    167      * Returns a MessageDigest object that implements the specified digest
    168      * algorithm.
    169      *
    170      * <p> This method traverses the list of registered security Providers,
    171      * starting with the most preferred Provider.
    172      * A new MessageDigest object encapsulating the
    173      * MessageDigestSpi implementation from the first
    174      * Provider that supports the specified algorithm is returned.
    175      *
    176      * <p> Note that the list of registered providers may be retrieved via
    177      * the {@link Security#getProviders() Security.getProviders()} method.
    178      *
    179      * @param algorithm the name of the algorithm requested.
    180      * See the MessageDigest section in the <a href=
    181      * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#MessageDigest">
    182      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
    183      * for information about standard algorithm names.
    184      *
    185      * @return a Message Digest object that implements the specified algorithm.
    186      *
    187      * @exception NoSuchAlgorithmException if no Provider supports a
    188      *          MessageDigestSpi implementation for the
    189      *          specified algorithm.
    190      *
    191      * @see Provider
    192      */
    193     public static MessageDigest getInstance(String algorithm)
    194     throws NoSuchAlgorithmException {
    195         try {
    196             MessageDigest md;
    197             Object[] objs = Security.getImpl(algorithm, "MessageDigest",
    198                                              (String)null);
    199             if (objs[0] instanceof MessageDigest) {
    200                 md = (MessageDigest)objs[0];
    201             } else {
    202                 md = new Delegate((MessageDigestSpi)objs[0], algorithm);
    203             }
    204             md.provider = (Provider)objs[1];
    205 
    206             // Android-removed: this debugging mechanism is not used in Android.
    207             /*
    208             if (!skipDebug && pdebug != null) {
    209                 pdebug.println("MessageDigest." + algorithm +
    210                     " algorithm from: " + md.provider.getName());
    211             }
    212             */
    213 
    214             return md;
    215 
    216         } catch(NoSuchProviderException e) {
    217             throw new NoSuchAlgorithmException(algorithm + " not found");
    218         }
    219     }
    220 
    221     /**
    222      * Returns a MessageDigest object that implements the specified digest
    223      * algorithm.
    224      *
    225      * <p> A new MessageDigest object encapsulating the
    226      * MessageDigestSpi implementation from the specified provider
    227      * is returned.  The specified provider must be registered
    228      * in the security provider list.
    229      *
    230      * <p> Note that the list of registered providers may be retrieved via
    231      * the {@link Security#getProviders() Security.getProviders()} method.
    232      *
    233      * @param algorithm the name of the algorithm requested.
    234      * See the MessageDigest section in the <a href=
    235      * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#MessageDigest">
    236      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
    237      * for information about standard algorithm names.
    238      *
    239      * @param provider the name of the provider.
    240      *
    241      * @return a MessageDigest object that implements the specified algorithm.
    242      *
    243      * @exception NoSuchAlgorithmException if a MessageDigestSpi
    244      *          implementation for the specified algorithm is not
    245      *          available from the specified provider.
    246      *
    247      * @exception NoSuchProviderException if the specified provider is not
    248      *          registered in the security provider list.
    249      *
    250      * @exception IllegalArgumentException if the provider name is null
    251      *          or empty.
    252      *
    253      * @see Provider
    254      */
    255     public static MessageDigest getInstance(String algorithm, String provider)
    256         throws NoSuchAlgorithmException, NoSuchProviderException
    257     {
    258         if (provider == null || provider.length() == 0)
    259             throw new IllegalArgumentException("missing provider");
    260         // Android-added: Check for Bouncy Castle deprecation
    261         Providers.checkBouncyCastleDeprecation(provider, "MessageDigest", algorithm);
    262         Object[] objs = Security.getImpl(algorithm, "MessageDigest", provider);
    263         if (objs[0] instanceof MessageDigest) {
    264             MessageDigest md = (MessageDigest)objs[0];
    265             md.provider = (Provider)objs[1];
    266             return md;
    267         } else {
    268             MessageDigest delegate =
    269                 new Delegate((MessageDigestSpi)objs[0], algorithm);
    270             delegate.provider = (Provider)objs[1];
    271             return delegate;
    272         }
    273     }
    274 
    275     /**
    276      * Returns a MessageDigest object that implements the specified digest
    277      * algorithm.
    278      *
    279      * <p> A new MessageDigest object encapsulating the
    280      * MessageDigestSpi implementation from the specified Provider
    281      * object is returned.  Note that the specified Provider object
    282      * does not have to be registered in the provider list.
    283      *
    284      * @param algorithm the name of the algorithm requested.
    285      * See the MessageDigest section in the <a href=
    286      * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#MessageDigest">
    287      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
    288      * for information about standard algorithm names.
    289      *
    290      * @param provider the provider.
    291      *
    292      * @return a MessageDigest object that implements the specified algorithm.
    293      *
    294      * @exception NoSuchAlgorithmException if a MessageDigestSpi
    295      *          implementation for the specified algorithm is not available
    296      *          from the specified Provider object.
    297      *
    298      * @exception IllegalArgumentException if the specified provider is null.
    299      *
    300      * @see Provider
    301      *
    302      * @since 1.4
    303      */
    304     public static MessageDigest getInstance(String algorithm,
    305                                             Provider provider)
    306         throws NoSuchAlgorithmException
    307     {
    308         if (provider == null)
    309             throw new IllegalArgumentException("missing provider");
    310         // Android-added: Check for Bouncy Castle deprecation
    311         Providers.checkBouncyCastleDeprecation(provider, "MessageDigest", algorithm);
    312         Object[] objs = Security.getImpl(algorithm, "MessageDigest", provider);
    313         if (objs[0] instanceof MessageDigest) {
    314             MessageDigest md = (MessageDigest)objs[0];
    315             md.provider = (Provider)objs[1];
    316             return md;
    317         } else {
    318             MessageDigest delegate =
    319                 new Delegate((MessageDigestSpi)objs[0], algorithm);
    320             delegate.provider = (Provider)objs[1];
    321             return delegate;
    322         }
    323     }
    324 
    325     /**
    326      * Returns the provider of this message digest object.
    327      *
    328      * @return the provider of this message digest object
    329      */
    330     public final Provider getProvider() {
    331         return this.provider;
    332     }
    333 
    334     /**
    335      * Updates the digest using the specified byte.
    336      *
    337      * @param input the byte with which to update the digest.
    338      */
    339     public void update(byte input) {
    340         engineUpdate(input);
    341         state = IN_PROGRESS;
    342     }
    343 
    344     /**
    345      * Updates the digest using the specified array of bytes, starting
    346      * at the specified offset.
    347      *
    348      * @param input the array of bytes.
    349      *
    350      * @param offset the offset to start from in the array of bytes.
    351      *
    352      * @param len the number of bytes to use, starting at
    353      * {@code offset}.
    354      */
    355     public void update(byte[] input, int offset, int len) {
    356         if (input == null) {
    357             throw new IllegalArgumentException("No input buffer given");
    358         }
    359         if (input.length - offset < len) {
    360             throw new IllegalArgumentException("Input buffer too short");
    361         }
    362         engineUpdate(input, offset, len);
    363         state = IN_PROGRESS;
    364     }
    365 
    366     /**
    367      * Updates the digest using the specified array of bytes.
    368      *
    369      * @param input the array of bytes.
    370      */
    371     public void update(byte[] input) {
    372         engineUpdate(input, 0, input.length);
    373         state = IN_PROGRESS;
    374     }
    375 
    376     /**
    377      * Update the digest using the specified ByteBuffer. The digest is
    378      * updated using the {@code input.remaining()} bytes starting
    379      * at {@code input.position()}.
    380      * Upon return, the buffer's position will be equal to its limit;
    381      * its limit will not have changed.
    382      *
    383      * @param input the ByteBuffer
    384      * @since 1.5
    385      */
    386     public final void update(ByteBuffer input) {
    387         if (input == null) {
    388             throw new NullPointerException();
    389         }
    390         engineUpdate(input);
    391         state = IN_PROGRESS;
    392     }
    393 
    394     /**
    395      * Completes the hash computation by performing final operations
    396      * such as padding. The digest is reset after this call is made.
    397      *
    398      * @return the array of bytes for the resulting hash value.
    399      */
    400     public byte[] digest() {
    401         /* Resetting is the responsibility of implementors. */
    402         byte[] result = engineDigest();
    403         state = INITIAL;
    404         return result;
    405     }
    406 
    407     /**
    408      * Completes the hash computation by performing final operations
    409      * such as padding. The digest is reset after this call is made.
    410      *
    411      * @param buf output buffer for the computed digest
    412      *
    413      * @param offset offset into the output buffer to begin storing the digest
    414      *
    415      * @param len number of bytes within buf allotted for the digest
    416      *
    417      * @return the number of bytes placed into {@code buf}
    418      *
    419      * @exception DigestException if an error occurs.
    420      */
    421     public int digest(byte[] buf, int offset, int len) throws DigestException {
    422         if (buf == null) {
    423             throw new IllegalArgumentException("No output buffer given");
    424         }
    425         if (buf.length - offset < len) {
    426             throw new IllegalArgumentException
    427                 ("Output buffer too small for specified offset and length");
    428         }
    429         int numBytes = engineDigest(buf, offset, len);
    430         state = INITIAL;
    431         return numBytes;
    432     }
    433 
    434     /**
    435      * Performs a final update on the digest using the specified array
    436      * of bytes, then completes the digest computation. That is, this
    437      * method first calls {@link #update(byte[]) update(input)},
    438      * passing the <i>input</i> array to the {@code update} method,
    439      * then calls {@link #digest() digest()}.
    440      *
    441      * @param input the input to be updated before the digest is
    442      * completed.
    443      *
    444      * @return the array of bytes for the resulting hash value.
    445      */
    446     public byte[] digest(byte[] input) {
    447         update(input);
    448         return digest();
    449     }
    450 
    451     /**
    452      * Returns a string representation of this message digest object.
    453      */
    454     public String toString() {
    455         // BEGIN Android-changed: Use StringBuilder instead of a ByteArrayOutputStream.
    456         StringBuilder builder = new StringBuilder();
    457         builder.append(algorithm);
    458         builder.append(" Message Digest from ");
    459         builder.append(provider.getName());
    460         builder.append(", ");
    461 
    462         switch (state) {
    463         case INITIAL:
    464             builder.append("<initialized>");
    465             break;
    466         case IN_PROGRESS:
    467             builder.append("<in progress>");
    468             break;
    469         }
    470 
    471         return builder.toString();
    472         // END Android-changed: Use StringBuilder instead of a ByteArrayOutputStream.
    473     }
    474 
    475     /**
    476      * Compares two digests for equality. Does a simple byte compare.
    477      *
    478      * @param digesta one of the digests to compare.
    479      *
    480      * @param digestb the other digest to compare.
    481      *
    482      * @return true if the digests are equal, false otherwise.
    483      */
    484     public static boolean isEqual(byte[] digesta, byte[] digestb) {
    485         if (digesta == digestb) return true;
    486         if (digesta == null || digestb == null) {
    487             return false;
    488         }
    489         if (digesta.length != digestb.length) {
    490             return false;
    491         }
    492 
    493         int result = 0;
    494         // time-constant comparison
    495         for (int i = 0; i < digesta.length; i++) {
    496             result |= digesta[i] ^ digestb[i];
    497         }
    498         return result == 0;
    499     }
    500 
    501     /**
    502      * Resets the digest for further use.
    503      */
    504     public void reset() {
    505         engineReset();
    506         state = INITIAL;
    507     }
    508 
    509     /**
    510      * Returns a string that identifies the algorithm, independent of
    511      * implementation details. The name should be a standard
    512      * Java Security name (such as "SHA", "MD5", and so on).
    513      * See the MessageDigest section in the <a href=
    514      * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#MessageDigest">
    515      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
    516      * for information about standard algorithm names.
    517      *
    518      * @return the name of the algorithm
    519      */
    520     public final String getAlgorithm() {
    521         return this.algorithm;
    522     }
    523 
    524     /**
    525      * Returns the length of the digest in bytes, or 0 if this operation is
    526      * not supported by the provider and the implementation is not cloneable.
    527      *
    528      * @return the digest length in bytes, or 0 if this operation is not
    529      * supported by the provider and the implementation is not cloneable.
    530      *
    531      * @since 1.2
    532      */
    533     public final int getDigestLength() {
    534         int digestLen = engineGetDigestLength();
    535         if (digestLen == 0) {
    536             try {
    537                 MessageDigest md = (MessageDigest)clone();
    538                 byte[] digest = md.digest();
    539                 return digest.length;
    540             } catch (CloneNotSupportedException e) {
    541                 return digestLen;
    542             }
    543         }
    544         return digestLen;
    545     }
    546 
    547     /**
    548      * Returns a clone if the implementation is cloneable.
    549      *
    550      * @return a clone if the implementation is cloneable.
    551      *
    552      * @exception CloneNotSupportedException if this is called on an
    553      * implementation that does not support {@code Cloneable}.
    554      */
    555     public Object clone() throws CloneNotSupportedException {
    556         if (this instanceof Cloneable) {
    557             return super.clone();
    558         } else {
    559             throw new CloneNotSupportedException();
    560         }
    561     }
    562 
    563 
    564 
    565 
    566     /*
    567      * The following class allows providers to extend from MessageDigestSpi
    568      * rather than from MessageDigest. It represents a MessageDigest with an
    569      * encapsulated, provider-supplied SPI object (of type MessageDigestSpi).
    570      * If the provider implementation is an instance of MessageDigestSpi,
    571      * the getInstance() methods above return an instance of this class, with
    572      * the SPI object encapsulated.
    573      *
    574      * Note: All SPI methods from the original MessageDigest class have been
    575      * moved up the hierarchy into a new class (MessageDigestSpi), which has
    576      * been interposed in the hierarchy between the API (MessageDigest)
    577      * and its original parent (Object).
    578      */
    579 
    580     static class Delegate extends MessageDigest {
    581 
    582         // The provider implementation (delegate)
    583         private MessageDigestSpi digestSpi;
    584 
    585         // constructor
    586         public Delegate(MessageDigestSpi digestSpi, String algorithm) {
    587             super(algorithm);
    588             this.digestSpi = digestSpi;
    589         }
    590 
    591         /**
    592          * Returns a clone if the delegate is cloneable.
    593          *
    594          * @return a clone if the delegate is cloneable.
    595          *
    596          * @exception CloneNotSupportedException if this is called on a
    597          * delegate that does not support {@code Cloneable}.
    598          */
    599         public Object clone() throws CloneNotSupportedException {
    600             if (digestSpi instanceof Cloneable) {
    601                 MessageDigestSpi digestSpiClone =
    602                     (MessageDigestSpi)digestSpi.clone();
    603                 // Because 'algorithm', 'provider', and 'state' are private
    604                 // members of our supertype, we must perform a cast to
    605                 // access them.
    606                 MessageDigest that =
    607                     new Delegate(digestSpiClone,
    608                                  ((MessageDigest)this).algorithm);
    609                 that.provider = ((MessageDigest)this).provider;
    610                 that.state = ((MessageDigest)this).state;
    611                 return that;
    612             } else {
    613                 throw new CloneNotSupportedException();
    614             }
    615         }
    616 
    617         protected int engineGetDigestLength() {
    618             return digestSpi.engineGetDigestLength();
    619         }
    620 
    621         protected void engineUpdate(byte input) {
    622             digestSpi.engineUpdate(input);
    623         }
    624 
    625         protected void engineUpdate(byte[] input, int offset, int len) {
    626             digestSpi.engineUpdate(input, offset, len);
    627         }
    628 
    629         protected void engineUpdate(ByteBuffer input) {
    630             digestSpi.engineUpdate(input);
    631         }
    632 
    633         protected byte[] engineDigest() {
    634             return digestSpi.engineDigest();
    635         }
    636 
    637         protected int engineDigest(byte[] buf, int offset, int len)
    638             throws DigestException {
    639                 return digestSpi.engineDigest(buf, offset, len);
    640         }
    641 
    642         protected void engineReset() {
    643             digestSpi.engineReset();
    644         }
    645     }
    646 }
    647