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
|