jdk/src/share/classes/com/sun/crypto/provider/TlsMasterSecretGenerator.java
changeset 2 90ce3da70b43
child 3353 ddbd63234844
equal deleted inserted replaced
0:fd16c54261b3 2:90ce3da70b43
       
     1 /*
       
     2  * Copyright 2005-2007 Sun Microsystems, Inc.  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.  Sun designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
       
    22  * CA 95054 USA or visit www.sun.com if you need additional information or
       
    23  * have any 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         SunJCE.ensureIntegrity(getClass());
       
    55     }
       
    56 
       
    57     protected void engineInit(SecureRandom random) {
       
    58         throw new InvalidParameterException(MSG);
       
    59     }
       
    60 
       
    61     protected void engineInit(AlgorithmParameterSpec params,
       
    62             SecureRandom random) throws InvalidAlgorithmParameterException {
       
    63         if (params instanceof TlsMasterSecretParameterSpec == false) {
       
    64             throw new InvalidAlgorithmParameterException(MSG);
       
    65         }
       
    66         this.spec = (TlsMasterSecretParameterSpec)params;
       
    67         if ("RAW".equals(spec.getPremasterSecret().getFormat()) == false) {
       
    68             throw new InvalidAlgorithmParameterException("Key format must be RAW");
       
    69         }
       
    70         protocolVersion = (spec.getMajorVersion() << 8) | spec.getMinorVersion();
       
    71         if ((protocolVersion < 0x0300) || (protocolVersion > 0x0302)) {
       
    72             throw new InvalidAlgorithmParameterException
       
    73                 ("Only SSL 3.0, TLS 1.0, and TLS 1.1 supported");
       
    74         }
       
    75     }
       
    76 
       
    77     protected void engineInit(int keysize, SecureRandom random) {
       
    78         throw new InvalidParameterException(MSG);
       
    79     }
       
    80 
       
    81     protected SecretKey engineGenerateKey() {
       
    82         if (spec == null) {
       
    83             throw new IllegalStateException
       
    84                 ("TlsMasterSecretGenerator must be initialized");
       
    85         }
       
    86         SecretKey premasterKey = spec.getPremasterSecret();
       
    87         byte[] premaster = premasterKey.getEncoded();
       
    88 
       
    89         int premasterMajor, premasterMinor;
       
    90         if (premasterKey.getAlgorithm().equals("TlsRsaPremasterSecret")) {
       
    91             // RSA
       
    92             premasterMajor = premaster[0] & 0xff;
       
    93             premasterMinor = premaster[1] & 0xff;
       
    94         } else {
       
    95             // DH, KRB5, others
       
    96             premasterMajor = -1;
       
    97             premasterMinor = -1;
       
    98         }
       
    99 
       
   100         try {
       
   101             byte[] master;
       
   102             byte[] clientRandom = spec.getClientRandom();
       
   103             byte[] serverRandom = spec.getServerRandom();
       
   104 
       
   105             if (protocolVersion >= 0x0301) {
       
   106                 byte[] seed = concat(clientRandom, serverRandom);
       
   107                 master = doPRF(premaster, LABEL_MASTER_SECRET, seed, 48);
       
   108             } else {
       
   109                 master = new byte[48];
       
   110                 MessageDigest md5 = MessageDigest.getInstance("MD5");
       
   111                 MessageDigest sha = MessageDigest.getInstance("SHA");
       
   112 
       
   113                 byte[] tmp = new byte[20];
       
   114                 for (int i = 0; i < 3; i++) {
       
   115                     sha.update(SSL3_CONST[i]);
       
   116                     sha.update(premaster);
       
   117                     sha.update(clientRandom);
       
   118                     sha.update(serverRandom);
       
   119                     sha.digest(tmp, 0, 20);
       
   120 
       
   121                     md5.update(premaster);
       
   122                     md5.update(tmp);
       
   123                     md5.digest(master, i << 4, 16);
       
   124                 }
       
   125 
       
   126             }
       
   127 
       
   128             return new TlsMasterSecretKey(master, premasterMajor, premasterMinor);
       
   129         } catch (NoSuchAlgorithmException e) {
       
   130             throw new ProviderException(e);
       
   131         } catch (DigestException e) {
       
   132             throw new ProviderException(e);
       
   133         }
       
   134     }
       
   135 
       
   136     private static final class TlsMasterSecretKey implements TlsMasterSecret {
       
   137 
       
   138         private byte[] key;
       
   139         private final int majorVersion, minorVersion;
       
   140 
       
   141         TlsMasterSecretKey(byte[] key, int majorVersion, int minorVersion) {
       
   142             this.key = key;
       
   143             this.majorVersion = majorVersion;
       
   144             this.minorVersion = minorVersion;
       
   145         }
       
   146 
       
   147         public int getMajorVersion() {
       
   148             return majorVersion;
       
   149         }
       
   150 
       
   151         public int getMinorVersion() {
       
   152             return minorVersion;
       
   153         }
       
   154 
       
   155         public String getAlgorithm() {
       
   156             return "TlsMasterSecret";
       
   157         }
       
   158 
       
   159         public String getFormat() {
       
   160             return "RAW";
       
   161         }
       
   162 
       
   163         public byte[] getEncoded() {
       
   164             return key.clone();
       
   165         }
       
   166 
       
   167     }
       
   168 
       
   169 }