< prev index next >

src/java.base/share/classes/sun/security/ssl/HandshakeMessage.java

Print this page




  32 import java.security.spec.*;
  33 import java.security.cert.*;
  34 import java.security.cert.Certificate;
  35 import java.util.*;
  36 import java.util.concurrent.ConcurrentHashMap;
  37 
  38 import java.lang.reflect.*;
  39 
  40 import javax.security.auth.x500.X500Principal;
  41 
  42 import javax.crypto.KeyGenerator;
  43 import javax.crypto.SecretKey;
  44 import javax.crypto.spec.DHPublicKeySpec;
  45 
  46 import javax.net.ssl.*;
  47 
  48 import sun.security.internal.spec.TlsPrfParameterSpec;
  49 import sun.security.ssl.CipherSuite.*;
  50 import static sun.security.ssl.CipherSuite.PRF.*;
  51 import sun.security.util.KeyUtil;

  52 import sun.security.provider.certpath.OCSPResponse;
  53 
  54 /**
  55  * Many data structures are involved in the handshake messages.  These
  56  * classes are used as structures, with public data members.  They are
  57  * not visible outside the SSL package.
  58  *
  59  * Handshake messages all have a common header format, and they are all
  60  * encoded in a "handshake data" SSL record substream.  The base class
  61  * here (HandshakeMessage) provides a common framework and records the
  62  * SSL record type of the particular handshake message.
  63  *
  64  * This file contains subclasses for all the basic handshake messages.
  65  * All handshake messages know how to encode and decode themselves on
  66  * SSL streams; this facilitates using the same code on SSL client and
  67  * server sides, although they don't send and receive the same messages.
  68  *
  69  * Messages also know how to print themselves, which is quite handy
  70  * for debugging.  They always identify their type, and can optionally
  71  * dump all of their content.


2107         // reflection API, so we avoid that if possible.
2108         byte[] keyBytes = "RAW".equals(masterSecret.getFormat())
2109                         ? masterSecret.getEncoded() : null;
2110         if (keyBytes != null) {
2111             md.update(keyBytes);
2112         } else {
2113             digestKey(md, masterSecret);
2114         }
2115         md.update(pad1);
2116         byte[] temp = md.digest();
2117 
2118         if (keyBytes != null) {
2119             md.update(keyBytes);
2120         } else {
2121             digestKey(md, masterSecret);
2122         }
2123         md.update(pad2);
2124         md.update(temp);
2125     }
2126 
2127     private static final Class<?> delegate;
2128     private static final Field spiField;
2129 
2130     static {
2131         try {
2132             delegate = Class.forName("java.security.MessageDigest$Delegate");
2133             spiField = delegate.getDeclaredField("digestSpi");
2134         } catch (Exception e) {
2135             throw new RuntimeException("Reflection failed", e);
2136         }
2137         makeAccessible(spiField);
2138     }
2139 
2140     private static void makeAccessible(final AccessibleObject o) {
2141         AccessController.doPrivileged(new PrivilegedAction<Object>() {
2142             @Override
2143             public Object run() {
2144                 o.setAccessible(true);
2145                 return null;
2146             }
2147         });
2148     }
2149 
2150     // ConcurrentHashMap does not allow null values, use this marker object
2151     private static final Object NULL_OBJECT = new Object();
2152 
2153     // cache Method objects per Spi class
2154     // Note that this will prevent the Spi classes from being GC'd. We assume
2155     // that is not a problem.
2156     private static final Map<Class<?>,Object> methodCache =
2157                                         new ConcurrentHashMap<>();
2158 
2159     private static void digestKey(MessageDigest md, SecretKey key) {
2160         try {
2161             // Verify that md is implemented via MessageDigestSpi, not
2162             // via JDK 1.1 style MessageDigest subclassing.
2163             if (md.getClass() != delegate) {
2164                 throw new Exception("Digest is not a MessageDigestSpi");
2165             }
2166             MessageDigestSpi spi = (MessageDigestSpi)spiField.get(md);
2167             Class<?> clazz = spi.getClass();
2168             Object r = methodCache.get(clazz);
2169             if (r == null) {
2170                 try {
2171                     r = clazz.getDeclaredMethod("implUpdate", SecretKey.class);
2172                     makeAccessible((Method)r);
2173                 } catch (NoSuchMethodException e) {
2174                     r = NULL_OBJECT;
2175                 }
2176                 methodCache.put(clazz, r);
2177             }
2178             if (r == NULL_OBJECT) {
2179                 throw new Exception(
2180                     "Digest does not support implUpdate(SecretKey)");
2181             }
2182             Method update = (Method)r;
2183             update.invoke(spi, key);
2184         } catch (Exception e) {
2185             throw new RuntimeException(
2186                 "Could not obtain encoded key and "
2187                 + "MessageDigest cannot digest key", e);
2188         }
2189     }
2190 
2191     @Override
2192     int messageType() {
2193         return ht_certificate_verify;
2194     }
2195 
2196     @Override
2197     int messageLength() {
2198         int temp = 2;
2199 
2200         if (protocolVersion.useTLS12PlusSpec()) {
2201             temp += SignatureAndHashAlgorithm.sizeInRecord();
2202         }
2203 




  32 import java.security.spec.*;
  33 import java.security.cert.*;
  34 import java.security.cert.Certificate;
  35 import java.util.*;
  36 import java.util.concurrent.ConcurrentHashMap;
  37 
  38 import java.lang.reflect.*;
  39 
  40 import javax.security.auth.x500.X500Principal;
  41 
  42 import javax.crypto.KeyGenerator;
  43 import javax.crypto.SecretKey;
  44 import javax.crypto.spec.DHPublicKeySpec;
  45 
  46 import javax.net.ssl.*;
  47 
  48 import sun.security.internal.spec.TlsPrfParameterSpec;
  49 import sun.security.ssl.CipherSuite.*;
  50 import static sun.security.ssl.CipherSuite.PRF.*;
  51 import sun.security.util.KeyUtil;
  52 import sun.security.util.MessageDigestSpi2;
  53 import sun.security.provider.certpath.OCSPResponse;
  54 
  55 /**
  56  * Many data structures are involved in the handshake messages.  These
  57  * classes are used as structures, with public data members.  They are
  58  * not visible outside the SSL package.
  59  *
  60  * Handshake messages all have a common header format, and they are all
  61  * encoded in a "handshake data" SSL record substream.  The base class
  62  * here (HandshakeMessage) provides a common framework and records the
  63  * SSL record type of the particular handshake message.
  64  *
  65  * This file contains subclasses for all the basic handshake messages.
  66  * All handshake messages know how to encode and decode themselves on
  67  * SSL streams; this facilitates using the same code on SSL client and
  68  * server sides, although they don't send and receive the same messages.
  69  *
  70  * Messages also know how to print themselves, which is quite handy
  71  * for debugging.  They always identify their type, and can optionally
  72  * dump all of their content.


2108         // reflection API, so we avoid that if possible.
2109         byte[] keyBytes = "RAW".equals(masterSecret.getFormat())
2110                         ? masterSecret.getEncoded() : null;
2111         if (keyBytes != null) {
2112             md.update(keyBytes);
2113         } else {
2114             digestKey(md, masterSecret);
2115         }
2116         md.update(pad1);
2117         byte[] temp = md.digest();
2118 
2119         if (keyBytes != null) {
2120             md.update(keyBytes);
2121         } else {
2122             digestKey(md, masterSecret);
2123         }
2124         md.update(pad2);
2125         md.update(temp);
2126     }
2127 
































2128     private static void digestKey(MessageDigest md, SecretKey key) {
2129         try {
2130             if (md instanceof MessageDigestSpi2) {
2131                 ((MessageDigestSpi2)md).engineUpdate(key);
2132             } else {















2133                 throw new Exception(
2134                     "Digest does not support implUpdate(SecretKey)");
2135             }


2136         } catch (Exception e) {
2137             throw new RuntimeException(
2138                 "Could not obtain encoded key and "
2139                 + "MessageDigest cannot digest key", e);
2140         }
2141     }
2142 
2143     @Override
2144     int messageType() {
2145         return ht_certificate_verify;
2146     }
2147 
2148     @Override
2149     int messageLength() {
2150         int temp = 2;
2151 
2152         if (protocolVersion.useTLS12PlusSpec()) {
2153             temp += SignatureAndHashAlgorithm.sizeInRecord();
2154         }
2155 


< prev index next >