Save This Page
Home » openjdk-7 » com.sun.crypto » provider » [javadoc | source]
    1   /*
    2    * Copyright (c) 2005, 2009, 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 com.sun.crypto.provider;
   27   
   28   import java.nio.ByteBuffer;
   29   
   30   import javax.crypto.MacSpi;
   31   import javax.crypto.SecretKey;
   32   import java.security;
   33   import java.security.spec.AlgorithmParameterSpec;
   34   
   35   import static com.sun.crypto.provider.TlsPrfGenerator.genPad;
   36   
   37   /**
   38    * This file contains the code for the SslMacMD5 and SslMacSHA1 implementations.
   39    * The SSL 3.0 MAC is a variation of the HMAC algorithm.
   40    *
   41    * Note that we don't implement Cloneable as that is not needed for SSL.
   42    *
   43    * @author  Andreas Sterbenz
   44    * @since   1.6
   45    */
   46   final class SslMacCore {
   47   
   48       private final MessageDigest md;
   49       private final byte[] pad1, pad2;
   50   
   51       private boolean first;       // Is this the first data to be processed?
   52       private byte[] secret;
   53   
   54       /**
   55        * Standard constructor, creates a new SslMacCore instance instantiating
   56        * a MessageDigest of the specified name.
   57        */
   58       SslMacCore(String digestAlgorithm, byte[] pad1, byte[] pad2)
   59               throws NoSuchAlgorithmException {
   60           md = MessageDigest.getInstance(digestAlgorithm);
   61           this.pad1 = pad1;
   62           this.pad2 = pad2;
   63           first = true;
   64       }
   65   
   66       /**
   67        * Returns the length of the Mac in bytes.
   68        *
   69        * @return the Mac length in bytes.
   70        */
   71       int getDigestLength() {
   72           return md.getDigestLength();
   73       }
   74   
   75       /**
   76        * Initializes the Mac with the given secret key and algorithm parameters.
   77        *
   78        * @param key the secret key.
   79        * @param params the algorithm parameters.
   80        *
   81        * @exception InvalidKeyException if the given key is inappropriate for
   82        * initializing this MAC.
   83        * @exception InvalidAlgorithmParameterException if the given algorithm
   84        * parameters are inappropriate for this MAC.
   85        */
   86       void init(Key key, AlgorithmParameterSpec params)
   87               throws InvalidKeyException, InvalidAlgorithmParameterException {
   88   
   89           if (params != null) {
   90               throw new InvalidAlgorithmParameterException
   91                   ("SslMac does not use parameters");
   92           }
   93   
   94           if (!(key instanceof SecretKey)) {
   95               throw new InvalidKeyException("Secret key expected");
   96           }
   97   
   98           secret = key.getEncoded();
   99           if (secret == null || secret.length == 0) {
  100               throw new InvalidKeyException("Missing key data");
  101           }
  102   
  103           reset();
  104       }
  105   
  106       /**
  107        * Processes the given byte.
  108        *
  109        * @param input the input byte to be processed.
  110        */
  111       void update(byte input) {
  112           if (first == true) {
  113               // compute digest for 1st pass; start with inner pad
  114               md.update(secret);
  115               md.update(pad1);
  116               first = false;
  117           }
  118   
  119           // add the passed byte to the inner digest
  120           md.update(input);
  121       }
  122   
  123       /**
  124        * Processes the first <code>len</code> bytes in <code>input</code>,
  125        * starting at <code>offset</code>.
  126        *
  127        * @param input the input buffer.
  128        * @param offset the offset in <code>input</code> where the input starts.
  129        * @param len the number of bytes to process.
  130        */
  131       void update(byte input[], int offset, int len) {
  132           if (first == true) {
  133               // compute digest for 1st pass; start with inner pad
  134               md.update(secret);
  135               md.update(pad1);
  136               first = false;
  137           }
  138   
  139           // add the selected part of an array of bytes to the inner digest
  140           md.update(input, offset, len);
  141       }
  142   
  143       void update(ByteBuffer input) {
  144           if (first == true) {
  145               // compute digest for 1st pass; start with inner pad
  146               md.update(secret);
  147               md.update(pad1);
  148               first = false;
  149           }
  150   
  151           md.update(input);
  152       }
  153   
  154       /**
  155        * Completes the Mac computation and resets the Mac for further use,
  156        * maintaining the secret key that the Mac was initialized with.
  157        *
  158        * @return the Mac result.
  159        */
  160       byte[] doFinal() {
  161           if (first == true) {
  162               // compute digest for 1st pass; start with inner pad
  163               md.update(secret);
  164               md.update(pad1);
  165           } else {
  166               first = true;
  167           }
  168   
  169           try {
  170               // finish the inner digest
  171               byte[] tmp = md.digest();
  172   
  173               // compute digest for 2nd pass; start with outer pad
  174               md.update(secret);
  175               md.update(pad2);
  176               // add result of 1st hash
  177               md.update(tmp);
  178   
  179               md.digest(tmp, 0, tmp.length);
  180               return tmp;
  181           } catch (DigestException e) {
  182               // should never occur
  183               throw new ProviderException(e);
  184           }
  185       }
  186   
  187       /**
  188        * Resets the Mac for further use, maintaining the secret key that the
  189        * Mac was initialized with.
  190        */
  191       void reset() {
  192           if (first == false) {
  193               md.reset();
  194               first = true;
  195           }
  196       }
  197   
  198       // nested static class for the SslMacMD5 implementation
  199       public static final class SslMacMD5 extends MacSpi {
  200           private final SslMacCore core;
  201           public SslMacMD5() throws NoSuchAlgorithmException {
  202               core = new SslMacCore("MD5", md5Pad1, md5Pad2);
  203           }
  204           protected int engineGetMacLength() {
  205               return core.getDigestLength();
  206           }
  207           protected void engineInit(Key key, AlgorithmParameterSpec params)
  208                   throws InvalidKeyException, InvalidAlgorithmParameterException {
  209               core.init(key, params);
  210           }
  211           protected void engineUpdate(byte input) {
  212               core.update(input);
  213           }
  214           protected void engineUpdate(byte input[], int offset, int len) {
  215               core.update(input, offset, len);
  216           }
  217           protected void engineUpdate(ByteBuffer input) {
  218               core.update(input);
  219           }
  220           protected byte[] engineDoFinal() {
  221               return core.doFinal();
  222           }
  223           protected void engineReset() {
  224               core.reset();
  225           }
  226   
  227           static final byte[] md5Pad1 = genPad((byte)0x36, 48);
  228           static final byte[] md5Pad2 = genPad((byte)0x5c, 48);
  229       }
  230   
  231       // nested static class for the SslMacMD5 implementation
  232       public static final class SslMacSHA1 extends MacSpi {
  233           private final SslMacCore core;
  234           public SslMacSHA1() throws NoSuchAlgorithmException {
  235               core = new SslMacCore("SHA", shaPad1, shaPad2);
  236           }
  237           protected int engineGetMacLength() {
  238               return core.getDigestLength();
  239           }
  240           protected void engineInit(Key key, AlgorithmParameterSpec params)
  241                   throws InvalidKeyException, InvalidAlgorithmParameterException {
  242               core.init(key, params);
  243           }
  244           protected void engineUpdate(byte input) {
  245               core.update(input);
  246           }
  247           protected void engineUpdate(byte input[], int offset, int len) {
  248               core.update(input, offset, len);
  249           }
  250           protected void engineUpdate(ByteBuffer input) {
  251               core.update(input);
  252           }
  253           protected byte[] engineDoFinal() {
  254               return core.doFinal();
  255           }
  256           protected void engineReset() {
  257               core.reset();
  258           }
  259   
  260           static final byte[] shaPad1 = genPad((byte)0x36, 40);
  261           static final byte[] shaPad2 = genPad((byte)0x5c, 40);
  262       }
  263   
  264   }

Save This Page
Home » openjdk-7 » com.sun.crypto » provider » [javadoc | source]