Save This Page
Home » openjdk-7 » com.sun.crypto » provider » [javadoc | source]
    1   /*
    2    * Copyright (c) 2005, 2010, 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.security;
   29   import java.security.spec.AlgorithmParameterSpec;
   30   
   31   import javax.crypto;
   32   
   33   import sun.security.internal.interfaces.TlsMasterSecret;
   34   import sun.security.internal.spec.TlsMasterSecretParameterSpec;
   35   
   36   import static com.sun.crypto.provider.TlsPrfGenerator.*;
   37   
   38   /**
   39    * KeyGenerator implementation for the SSL/TLS master secret derivation.
   40    *
   41    * @author  Andreas Sterbenz
   42    * @since   1.6
   43    */
   44   public final class TlsMasterSecretGenerator extends KeyGeneratorSpi {
   45   
   46       private final static String MSG = "TlsMasterSecretGenerator must be "
   47           + "initialized using a TlsMasterSecretParameterSpec";
   48   
   49       private TlsMasterSecretParameterSpec spec;
   50   
   51       private int protocolVersion;
   52   
   53       public TlsMasterSecretGenerator() {
   54       }
   55   
   56       protected void engineInit(SecureRandom random) {
   57           throw new InvalidParameterException(MSG);
   58       }
   59   
   60       protected void engineInit(AlgorithmParameterSpec params,
   61               SecureRandom random) throws InvalidAlgorithmParameterException {
   62           if (params instanceof TlsMasterSecretParameterSpec == false) {
   63               throw new InvalidAlgorithmParameterException(MSG);
   64           }
   65           this.spec = (TlsMasterSecretParameterSpec)params;
   66           if ("RAW".equals(spec.getPremasterSecret().getFormat()) == false) {
   67               throw new InvalidAlgorithmParameterException(
   68                   "Key format must be RAW");
   69           }
   70           protocolVersion = (spec.getMajorVersion() << 8)
   71               | spec.getMinorVersion();
   72           if ((protocolVersion < 0x0300) || (protocolVersion > 0x0303)) {
   73               throw new InvalidAlgorithmParameterException(
   74                   "Only SSL 3.0, TLS 1.0/1.1/1.2 supported");
   75           }
   76       }
   77   
   78       protected void engineInit(int keysize, SecureRandom random) {
   79           throw new InvalidParameterException(MSG);
   80       }
   81   
   82       protected SecretKey engineGenerateKey() {
   83           if (spec == null) {
   84               throw new IllegalStateException(
   85                   "TlsMasterSecretGenerator must be initialized");
   86           }
   87           SecretKey premasterKey = spec.getPremasterSecret();
   88           byte[] premaster = premasterKey.getEncoded();
   89   
   90           int premasterMajor, premasterMinor;
   91           if (premasterKey.getAlgorithm().equals("TlsRsaPremasterSecret")) {
   92               // RSA
   93               premasterMajor = premaster[0] & 0xff;
   94               premasterMinor = premaster[1] & 0xff;
   95           } else {
   96               // DH, KRB5, others
   97               premasterMajor = -1;
   98               premasterMinor = -1;
   99           }
  100   
  101           try {
  102               byte[] master;
  103               byte[] clientRandom = spec.getClientRandom();
  104               byte[] serverRandom = spec.getServerRandom();
  105   
  106               if (protocolVersion >= 0x0301) {
  107                   byte[] seed = concat(clientRandom, serverRandom);
  108                   master = ((protocolVersion >= 0x0303) ?
  109                       doTLS12PRF(premaster, LABEL_MASTER_SECRET, seed, 48,
  110                           spec.getPRFHashAlg(), spec.getPRFHashLength(),
  111                           spec.getPRFBlockSize()) :
  112                       doTLS10PRF(premaster, LABEL_MASTER_SECRET, seed, 48));
  113               } else {
  114                   master = new byte[48];
  115                   MessageDigest md5 = MessageDigest.getInstance("MD5");
  116                   MessageDigest sha = MessageDigest.getInstance("SHA");
  117   
  118                   byte[] tmp = new byte[20];
  119                   for (int i = 0; i < 3; i++) {
  120                       sha.update(SSL3_CONST[i]);
  121                       sha.update(premaster);
  122                       sha.update(clientRandom);
  123                       sha.update(serverRandom);
  124                       sha.digest(tmp, 0, 20);
  125   
  126                       md5.update(premaster);
  127                       md5.update(tmp);
  128                       md5.digest(master, i << 4, 16);
  129                   }
  130   
  131               }
  132   
  133               return new TlsMasterSecretKey(master, premasterMajor,
  134                   premasterMinor);
  135           } catch (NoSuchAlgorithmException e) {
  136               throw new ProviderException(e);
  137           } catch (DigestException e) {
  138               throw new ProviderException(e);
  139           }
  140       }
  141   
  142       private static final class TlsMasterSecretKey implements TlsMasterSecret {
  143   
  144           private byte[] key;
  145           private final int majorVersion, minorVersion;
  146   
  147           TlsMasterSecretKey(byte[] key, int majorVersion, int minorVersion) {
  148               this.key = key;
  149               this.majorVersion = majorVersion;
  150               this.minorVersion = minorVersion;
  151           }
  152   
  153           public int getMajorVersion() {
  154               return majorVersion;
  155           }
  156   
  157           public int getMinorVersion() {
  158               return minorVersion;
  159           }
  160   
  161           public String getAlgorithm() {
  162               return "TlsMasterSecret";
  163           }
  164   
  165           public String getFormat() {
  166               return "RAW";
  167           }
  168   
  169           public byte[] getEncoded() {
  170               return key.clone();
  171           }
  172   
  173       }
  174   
  175   }

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