71 * |
71 * |
72 * @author David Brownell |
72 * @author David Brownell |
73 */ |
73 */ |
74 public abstract class HandshakeMessage { |
74 public abstract class HandshakeMessage { |
75 |
75 |
76 HandshakeMessage() { } |
|
77 |
|
78 // enum HandshakeType: |
|
79 static final byte ht_hello_request = 0; |
|
80 static final byte ht_client_hello = 1; |
|
81 static final byte ht_server_hello = 2; |
|
82 |
|
83 static final byte ht_certificate = 11; |
|
84 static final byte ht_server_key_exchange = 12; |
|
85 static final byte ht_certificate_request = 13; |
|
86 static final byte ht_server_hello_done = 14; |
|
87 static final byte ht_certificate_verify = 15; |
|
88 static final byte ht_client_key_exchange = 16; |
|
89 |
|
90 static final byte ht_finished = 20; |
|
91 |
|
92 /* Class and subclass dynamic debugging support */ |
76 /* Class and subclass dynamic debugging support */ |
93 public static final Debug debug = Debug.getInstance("ssl"); |
77 public static final Debug debug = Debug.getInstance("ssl"); |
|
78 |
|
79 // enum HandshakeType: |
|
80 static final byte ht_hello_request = 0; // RFC 5246 |
|
81 static final byte ht_client_hello = 1; // RFC 5246 |
|
82 static final byte ht_server_hello = 2; // RFC 5246 |
|
83 static final byte ht_hello_verify_request = 3; // RFC 6347 |
|
84 static final byte ht_new_session_ticket = 4; // RFC 4507 |
|
85 |
|
86 static final byte ht_certificate = 11; // RFC 5246 |
|
87 static final byte ht_server_key_exchange = 12; // RFC 5246 |
|
88 static final byte ht_certificate_request = 13; // RFC 5246 |
|
89 static final byte ht_server_hello_done = 14; // RFC 5246 |
|
90 static final byte ht_certificate_verify = 15; // RFC 5246 |
|
91 static final byte ht_client_key_exchange = 16; // RFC 5246 |
|
92 |
|
93 static final byte ht_finished = 20; // RFC 5246 |
|
94 static final byte ht_certificate_url = 21; // RFC 6066 |
|
95 static final byte ht_certificate_status = 22; // RFC 6066 |
|
96 static final byte ht_supplemental_data = 23; // RFC 4680 |
|
97 |
|
98 static final byte ht_not_applicable = -1; // N/A |
|
99 |
|
100 /* |
|
101 * SSL 3.0 MAC padding constants. |
|
102 * Also used by CertificateVerify and Finished during the handshake. |
|
103 */ |
|
104 static final byte[] MD5_pad1 = genPad(0x36, 48); |
|
105 static final byte[] MD5_pad2 = genPad(0x5c, 48); |
|
106 |
|
107 static final byte[] SHA_pad1 = genPad(0x36, 40); |
|
108 static final byte[] SHA_pad2 = genPad(0x5c, 40); |
|
109 |
|
110 // default constructor |
|
111 HandshakeMessage() { |
|
112 } |
94 |
113 |
95 /** |
114 /** |
96 * Utility method to convert a BigInteger to a byte array in unsigned |
115 * Utility method to convert a BigInteger to a byte array in unsigned |
97 * format as needed in the handshake messages. BigInteger uses |
116 * format as needed in the handshake messages. BigInteger uses |
98 * 2's complement format, i.e. it prepends an extra zero if the MSB |
117 * 2's complement format, i.e. it prepends an extra zero if the MSB |
107 b = newarray; |
126 b = newarray; |
108 } |
127 } |
109 return b; |
128 return b; |
110 } |
129 } |
111 |
130 |
112 /* |
|
113 * SSL 3.0 MAC padding constants. |
|
114 * Also used by CertificateVerify and Finished during the handshake. |
|
115 */ |
|
116 static final byte[] MD5_pad1 = genPad(0x36, 48); |
|
117 static final byte[] MD5_pad2 = genPad(0x5c, 48); |
|
118 |
|
119 static final byte[] SHA_pad1 = genPad(0x36, 40); |
|
120 static final byte[] SHA_pad2 = genPad(0x5c, 40); |
|
121 |
|
122 private static byte[] genPad(int b, int count) { |
131 private static byte[] genPad(int b, int count) { |
123 byte[] padding = new byte[count]; |
132 byte[] padding = new byte[count]; |
124 Arrays.fill(padding, (byte)b); |
133 Arrays.fill(padding, (byte)b); |
125 return padding; |
134 return padding; |
126 } |
135 } |
197 out.println("*** HelloRequest (empty)"); |
207 out.println("*** HelloRequest (empty)"); |
198 } |
208 } |
199 |
209 |
200 } |
210 } |
201 |
211 |
|
212 /* |
|
213 * HelloVerifyRequest ... SERVER --> CLIENT [DTLS only] |
|
214 * |
|
215 * The definition of HelloVerifyRequest is as follows: |
|
216 * |
|
217 * struct { |
|
218 * ProtocolVersion server_version; |
|
219 * opaque cookie<0..2^8-1>; |
|
220 * } HelloVerifyRequest; |
|
221 * |
|
222 * For DTLS protocols, once the client has transmitted the ClientHello message, |
|
223 * it expects to see a HelloVerifyRequest from the server. However, if the |
|
224 * server's message is lost, the client knows that either the ClientHello or |
|
225 * the HelloVerifyRequest has been lost and retransmits. [RFC 6347] |
|
226 */ |
|
227 static final class HelloVerifyRequest extends HandshakeMessage { |
|
228 ProtocolVersion protocolVersion; |
|
229 byte[] cookie; // 1 to 2^8 - 1 bytes |
|
230 |
|
231 HelloVerifyRequest(HelloCookieManager helloCookieManager, |
|
232 ClientHello clientHelloMsg) { |
|
233 |
|
234 this.protocolVersion = clientHelloMsg.protocolVersion; |
|
235 this.cookie = helloCookieManager.getCookie(clientHelloMsg); |
|
236 } |
|
237 |
|
238 HelloVerifyRequest( |
|
239 HandshakeInStream input, int messageLength) throws IOException { |
|
240 |
|
241 this.protocolVersion = |
|
242 ProtocolVersion.valueOf(input.getInt8(), input.getInt8()); |
|
243 this.cookie = input.getBytes8(); |
|
244 |
|
245 // Is it a valid cookie? |
|
246 HelloCookieManager.checkCookie(protocolVersion, cookie); |
|
247 } |
|
248 |
|
249 @Override |
|
250 int messageType() { |
|
251 return ht_hello_verify_request; |
|
252 } |
|
253 |
|
254 @Override |
|
255 int messageLength() { |
|
256 return 2 + cookie.length; // 2: the length of protocolVersion |
|
257 } |
|
258 |
|
259 @Override |
|
260 void send(HandshakeOutStream hos) throws IOException { |
|
261 hos.putInt8(protocolVersion.major); |
|
262 hos.putInt8(protocolVersion.minor); |
|
263 hos.putBytes8(cookie); |
|
264 } |
|
265 |
|
266 @Override |
|
267 void print(PrintStream out) throws IOException { |
|
268 out.println("*** HelloVerifyRequest"); |
|
269 if (debug != null && Debug.isOn("verbose")) { |
|
270 out.println("server_version: " + protocolVersion); |
|
271 Debug.println(out, "cookie", cookie); |
|
272 } |
|
273 } |
|
274 } |
202 |
275 |
203 /* |
276 /* |
204 * ClientHello ... CLIENT --> SERVER |
277 * ClientHello ... CLIENT --> SERVER |
205 * |
278 * |
206 * Client initiates handshake by telling server what it wants, and what it |
279 * Client initiates handshake by telling server what it wants, and what it |
211 * Until we know how to parse it, we will just read what we know |
284 * Until we know how to parse it, we will just read what we know |
212 * about, and let our caller handle the jumps over unknown data. |
285 * about, and let our caller handle the jumps over unknown data. |
213 */ |
286 */ |
214 static final class ClientHello extends HandshakeMessage { |
287 static final class ClientHello extends HandshakeMessage { |
215 |
288 |
216 ProtocolVersion protocolVersion; |
289 ProtocolVersion protocolVersion; |
217 RandomCookie clnt_random; |
290 RandomCookie clnt_random; |
218 SessionId sessionId; |
291 SessionId sessionId; |
219 private CipherSuiteList cipherSuites; |
292 byte[] cookie; // DTLS only |
220 byte[] compression_methods; |
293 private CipherSuiteList cipherSuites; |
|
294 private final boolean isDTLS; |
|
295 byte[] compression_methods; |
221 |
296 |
222 HelloExtensions extensions = new HelloExtensions(); |
297 HelloExtensions extensions = new HelloExtensions(); |
223 |
298 |
224 private final static byte[] NULL_COMPRESSION = new byte[] {0}; |
299 private final static byte[] NULL_COMPRESSION = new byte[] {0}; |
225 |
300 |
226 ClientHello(SecureRandom generator, ProtocolVersion protocolVersion, |
301 ClientHello(SecureRandom generator, ProtocolVersion protocolVersion, |
227 SessionId sessionId, CipherSuiteList cipherSuites) { |
302 SessionId sessionId, CipherSuiteList cipherSuites, |
228 |
303 boolean isDTLS) { |
|
304 |
|
305 this.isDTLS = isDTLS; |
229 this.protocolVersion = protocolVersion; |
306 this.protocolVersion = protocolVersion; |
230 this.sessionId = sessionId; |
307 this.sessionId = sessionId; |
231 this.cipherSuites = cipherSuites; |
308 this.cipherSuites = cipherSuites; |
|
309 if (isDTLS) { |
|
310 this.cookie = new byte[0]; |
|
311 } else { |
|
312 this.cookie = null; |
|
313 } |
232 |
314 |
233 if (cipherSuites.containsEC()) { |
315 if (cipherSuites.containsEC()) { |
234 extensions.add(SupportedEllipticCurvesExtension.DEFAULT); |
316 extensions.add(SupportedEllipticCurvesExtension.DEFAULT); |
235 extensions.add(SupportedEllipticPointFormatsExtension.DEFAULT); |
317 extensions.add(SupportedEllipticPointFormatsExtension.DEFAULT); |
236 } |
318 } |
237 |
319 |
238 clnt_random = new RandomCookie(generator); |
320 clnt_random = new RandomCookie(generator); |
239 compression_methods = NULL_COMPRESSION; |
321 compression_methods = NULL_COMPRESSION; |
240 } |
322 } |
241 |
323 |
242 ClientHello(HandshakeInStream s, int messageLength) throws IOException { |
324 ClientHello(HandshakeInStream s, |
|
325 int messageLength, boolean isDTLS) throws IOException { |
|
326 |
|
327 this.isDTLS = isDTLS; |
|
328 |
243 protocolVersion = ProtocolVersion.valueOf(s.getInt8(), s.getInt8()); |
329 protocolVersion = ProtocolVersion.valueOf(s.getInt8(), s.getInt8()); |
244 clnt_random = new RandomCookie(s); |
330 clnt_random = new RandomCookie(s); |
245 sessionId = new SessionId(s.getBytes8()); |
331 sessionId = new SessionId(s.getBytes8()); |
246 sessionId.checkLength(protocolVersion); |
332 sessionId.checkLength(protocolVersion); |
|
333 if (isDTLS) { |
|
334 cookie = s.getBytes8(); |
|
335 } else { |
|
336 cookie = null; |
|
337 } |
|
338 |
247 cipherSuites = new CipherSuiteList(s); |
339 cipherSuites = new CipherSuiteList(s); |
248 compression_methods = s.getBytes8(); |
340 compression_methods = s.getBytes8(); |
249 if (messageLength() != messageLength) { |
341 if (messageLength() != messageLength) { |
250 extensions = new HelloExtensions(s); |
342 extensions = new HelloExtensions(s); |
251 } |
343 } |
275 void addSignatureAlgorithmsExtension( |
367 void addSignatureAlgorithmsExtension( |
276 Collection<SignatureAndHashAlgorithm> algorithms) { |
368 Collection<SignatureAndHashAlgorithm> algorithms) { |
277 HelloExtension signatureAlgorithm = |
369 HelloExtension signatureAlgorithm = |
278 new SignatureAlgorithmsExtension(algorithms); |
370 new SignatureAlgorithmsExtension(algorithms); |
279 extensions.add(signatureAlgorithm); |
371 extensions.add(signatureAlgorithm); |
|
372 } |
|
373 |
|
374 void addMFLExtension(int maximumPacketSize) { |
|
375 HelloExtension maxFragmentLength = |
|
376 new MaxFragmentLengthExtension(maximumPacketSize); |
|
377 extensions.add(maxFragmentLength); |
|
378 } |
|
379 |
|
380 void updateHelloCookie(MessageDigest cookieDigest) { |
|
381 // |
|
382 // Just use HandshakeOutStream to compute the hello verify cookie. |
|
383 // Not actually used to output handshake message records. |
|
384 // |
|
385 HandshakeOutStream hos = new HandshakeOutStream(null); |
|
386 |
|
387 try { |
|
388 send(hos, false); // Do not count hello verify cookie. |
|
389 } catch (IOException ioe) { |
|
390 // unlikely to happen |
|
391 } |
|
392 |
|
393 cookieDigest.update(hos.toByteArray()); |
280 } |
394 } |
281 |
395 |
282 @Override |
396 @Override |
283 int messageType() { return ht_client_hello; } |
397 int messageType() { return ht_client_hello; } |
284 |
398 |
288 * Add fixed size parts of each field... |
402 * Add fixed size parts of each field... |
289 * version + random + session + cipher + compress |
403 * version + random + session + cipher + compress |
290 */ |
404 */ |
291 return (2 + 32 + 1 + 2 + 1 |
405 return (2 + 32 + 1 + 2 + 1 |
292 + sessionId.length() /* ... + variable parts */ |
406 + sessionId.length() /* ... + variable parts */ |
|
407 + (isDTLS ? (1 + cookie.length) : 0) |
293 + (cipherSuites.size() * 2) |
408 + (cipherSuites.size() * 2) |
294 + compression_methods.length) |
409 + compression_methods.length) |
295 + extensions.length(); |
410 + extensions.length(); |
296 } |
411 } |
297 |
412 |
298 @Override |
413 @Override |
299 void send(HandshakeOutStream s) throws IOException { |
414 void send(HandshakeOutStream s) throws IOException { |
|
415 send(s, true); // Count hello verify cookie. |
|
416 } |
|
417 |
|
418 @Override |
|
419 void print(PrintStream s) throws IOException { |
|
420 s.println("*** ClientHello, " + protocolVersion); |
|
421 |
|
422 if (debug != null && Debug.isOn("verbose")) { |
|
423 s.print("RandomCookie: "); |
|
424 clnt_random.print(s); |
|
425 |
|
426 s.print("Session ID: "); |
|
427 s.println(sessionId); |
|
428 |
|
429 if (isDTLS) { |
|
430 Debug.println(s, "cookie", cookie); |
|
431 } |
|
432 |
|
433 s.println("Cipher Suites: " + cipherSuites); |
|
434 |
|
435 Debug.println(s, "Compression Methods", compression_methods); |
|
436 extensions.print(s); |
|
437 s.println("***"); |
|
438 } |
|
439 } |
|
440 |
|
441 private void send(HandshakeOutStream s, |
|
442 boolean computeCookie) throws IOException { |
300 s.putInt8(protocolVersion.major); |
443 s.putInt8(protocolVersion.major); |
301 s.putInt8(protocolVersion.minor); |
444 s.putInt8(protocolVersion.minor); |
302 clnt_random.send(s); |
445 clnt_random.send(s); |
303 s.putBytes8(sessionId.getId()); |
446 s.putBytes8(sessionId.getId()); |
|
447 if (isDTLS && computeCookie) { |
|
448 s.putBytes8(cookie); |
|
449 } |
304 cipherSuites.send(s); |
450 cipherSuites.send(s); |
305 s.putBytes8(compression_methods); |
451 s.putBytes8(compression_methods); |
306 extensions.send(s); |
452 extensions.send(s); |
307 } |
453 } |
308 |
454 |
309 @Override |
|
310 void print(PrintStream s) throws IOException { |
|
311 s.println("*** ClientHello, " + protocolVersion); |
|
312 |
|
313 if (debug != null && Debug.isOn("verbose")) { |
|
314 s.print("RandomCookie: "); |
|
315 clnt_random.print(s); |
|
316 |
|
317 s.print("Session ID: "); |
|
318 s.println(sessionId); |
|
319 |
|
320 s.println("Cipher Suites: " + cipherSuites); |
|
321 |
|
322 Debug.println(s, "Compression Methods", compression_methods); |
|
323 extensions.print(s); |
|
324 s.println("***"); |
|
325 } |
|
326 } |
|
327 } |
455 } |
328 |
456 |
329 /* |
457 /* |
330 * ServerHello ... SERVER --> CLIENT |
458 * ServerHello ... SERVER --> CLIENT |
331 * |
459 * |
799 KeyUtil.validate(new DHPublicKeySpec(new BigInteger(1, dh_Ys), |
927 KeyUtil.validate(new DHPublicKeySpec(new BigInteger(1, dh_Ys), |
800 new BigInteger(1, dh_p), |
928 new BigInteger(1, dh_p), |
801 new BigInteger(1, dh_g))); |
929 new BigInteger(1, dh_g))); |
802 |
930 |
803 // read the signature and hash algorithm |
931 // read the signature and hash algorithm |
804 if (protocolVersion.v >= ProtocolVersion.TLS12.v) { |
932 if (protocolVersion.useTLS12PlusSpec()) { |
805 int hash = input.getInt8(); // hash algorithm |
933 int hash = input.getInt8(); // hash algorithm |
806 int signature = input.getInt8(); // signature algorithm |
934 int signature = input.getInt8(); // signature algorithm |
807 |
935 |
808 preferableSignatureAlgorithm = |
936 preferableSignatureAlgorithm = |
809 SignatureAndHashAlgorithm.valueOf(hash, signature, 0); |
937 SignatureAndHashAlgorithm.valueOf(hash, signature, 0); |
957 Debug.println(s, "Server DH Public Key", dh_Ys); |
1085 Debug.println(s, "Server DH Public Key", dh_Ys); |
958 |
1086 |
959 if (signature == null) { |
1087 if (signature == null) { |
960 s.println("Anonymous"); |
1088 s.println("Anonymous"); |
961 } else { |
1089 } else { |
962 if (protocolVersion.v >= ProtocolVersion.TLS12.v) { |
1090 if (protocolVersion.useTLS12PlusSpec()) { |
963 s.println("Signature Algorithm " + |
1091 s.println("Signature Algorithm " + |
964 preferableSignatureAlgorithm.getAlgorithmName()); |
1092 preferableSignatureAlgorithm.getAlgorithmName()); |
965 } |
1093 } |
966 |
1094 |
967 s.println("Signed with a DSA or RSA public key"); |
1095 s.println("Signed with a DSA or RSA public key"); |
1170 s.putInt8(CURVE_NAMED_CURVE); |
1298 s.putInt8(CURVE_NAMED_CURVE); |
1171 s.putInt16(curveId); |
1299 s.putInt16(curveId); |
1172 s.putBytes8(pointBytes); |
1300 s.putBytes8(pointBytes); |
1173 |
1301 |
1174 if (signatureBytes != null) { |
1302 if (signatureBytes != null) { |
1175 if (protocolVersion.v >= ProtocolVersion.TLS12.v) { |
1303 if (protocolVersion.useTLS12PlusSpec()) { |
1176 s.putInt8(preferableSignatureAlgorithm.getHashValue()); |
1304 s.putInt8(preferableSignatureAlgorithm.getHashValue()); |
1177 s.putInt8(preferableSignatureAlgorithm.getSignatureValue()); |
1305 s.putInt8(preferableSignatureAlgorithm.getSignatureValue()); |
1178 } |
1306 } |
1179 |
1307 |
1180 s.putBytes16(signatureBytes); |
1308 s.putBytes16(signatureBytes); |
1313 // needs to be adapted to take keyExchange into account. |
1441 // needs to be adapted to take keyExchange into account. |
1314 // We only request ECDSA client auth if we have ECC crypto available. |
1442 // We only request ECDSA client auth if we have ECC crypto available. |
1315 this.types = JsseJce.isEcAvailable() ? TYPES_ECC : TYPES_NO_ECC; |
1443 this.types = JsseJce.isEcAvailable() ? TYPES_ECC : TYPES_NO_ECC; |
1316 |
1444 |
1317 // Use supported_signature_algorithms for TLS 1.2 or later. |
1445 // Use supported_signature_algorithms for TLS 1.2 or later. |
1318 if (protocolVersion.v >= ProtocolVersion.TLS12.v) { |
1446 if (protocolVersion.useTLS12PlusSpec()) { |
1319 if (signAlgs == null || signAlgs.isEmpty()) { |
1447 if (signAlgs == null || signAlgs.isEmpty()) { |
1320 throw new SSLProtocolException( |
1448 throw new SSLProtocolException( |
1321 "No supported signature algorithms"); |
1449 "No supported signature algorithms"); |
1322 } |
1450 } |
1323 |
1451 |
1337 |
1465 |
1338 // Read the certificate_types. |
1466 // Read the certificate_types. |
1339 types = input.getBytes8(); |
1467 types = input.getBytes8(); |
1340 |
1468 |
1341 // Read the supported_signature_algorithms for TLS 1.2 or later. |
1469 // Read the supported_signature_algorithms for TLS 1.2 or later. |
1342 if (protocolVersion.v >= ProtocolVersion.TLS12.v) { |
1470 if (protocolVersion.useTLS12PlusSpec()) { |
1343 algorithmsLen = input.getInt16(); |
1471 algorithmsLen = input.getInt16(); |
1344 if (algorithmsLen < 2) { |
1472 if (algorithmsLen < 2) { |
1345 throw new SSLProtocolException( |
1473 throw new SSLProtocolException( |
1346 "Invalid supported_signature_algorithms field"); |
1474 "Invalid supported_signature_algorithms field"); |
1347 } |
1475 } |
1421 void send(HandshakeOutStream output) throws IOException { |
1549 void send(HandshakeOutStream output) throws IOException { |
1422 // put certificate_types |
1550 // put certificate_types |
1423 output.putBytes8(types); |
1551 output.putBytes8(types); |
1424 |
1552 |
1425 // put supported_signature_algorithms |
1553 // put supported_signature_algorithms |
1426 if (protocolVersion.v >= ProtocolVersion.TLS12.v) { |
1554 if (protocolVersion.useTLS12PlusSpec()) { |
1427 output.putInt16(algorithmsLen); |
1555 output.putInt16(algorithmsLen); |
1428 for (SignatureAndHashAlgorithm algorithm : algorithms) { |
1556 for (SignatureAndHashAlgorithm algorithm : algorithms) { |
1429 output.putInt8(algorithm.getHashValue()); // hash |
1557 output.putInt8(algorithm.getHashValue()); // hash |
1430 output.putInt8(algorithm.getSignatureValue()); // signature |
1558 output.putInt8(algorithm.getSignatureValue()); // signature |
1431 } |
1559 } |
1574 |
1702 |
1575 this.protocolVersion = protocolVersion; |
1703 this.protocolVersion = protocolVersion; |
1576 |
1704 |
1577 String algorithm = privateKey.getAlgorithm(); |
1705 String algorithm = privateKey.getAlgorithm(); |
1578 Signature sig = null; |
1706 Signature sig = null; |
1579 if (protocolVersion.v >= ProtocolVersion.TLS12.v) { |
1707 if (protocolVersion.useTLS12PlusSpec()) { |
1580 this.preferableSignatureAlgorithm = signAlgorithm; |
1708 this.preferableSignatureAlgorithm = signAlgorithm; |
1581 sig = JsseJce.getSignature(signAlgorithm.getAlgorithmName()); |
1709 sig = JsseJce.getSignature(signAlgorithm.getAlgorithmName()); |
1582 } else { |
1710 } else { |
1583 sig = getSignature(protocolVersion, algorithm); |
1711 sig = getSignature(protocolVersion, algorithm); |
1584 } |
1712 } |
1596 ProtocolVersion protocolVersion) throws IOException { |
1724 ProtocolVersion protocolVersion) throws IOException { |
1597 |
1725 |
1598 this.protocolVersion = protocolVersion; |
1726 this.protocolVersion = protocolVersion; |
1599 |
1727 |
1600 // read the signature and hash algorithm |
1728 // read the signature and hash algorithm |
1601 if (protocolVersion.v >= ProtocolVersion.TLS12.v) { |
1729 if (protocolVersion.useTLS12PlusSpec()) { |
1602 int hashAlg = input.getInt8(); // hash algorithm |
1730 int hashAlg = input.getInt8(); // hash algorithm |
1603 int signAlg = input.getInt8(); // signature algorithm |
1731 int signAlg = input.getInt8(); // signature algorithm |
1604 |
1732 |
1605 preferableSignatureAlgorithm = |
1733 preferableSignatureAlgorithm = |
1606 SignatureAndHashAlgorithm.valueOf(hashAlg, signAlg, 0); |
1734 SignatureAndHashAlgorithm.valueOf(hashAlg, signAlg, 0); |
1632 boolean verify(ProtocolVersion protocolVersion, |
1760 boolean verify(ProtocolVersion protocolVersion, |
1633 HandshakeHash handshakeHash, PublicKey publicKey, |
1761 HandshakeHash handshakeHash, PublicKey publicKey, |
1634 SecretKey masterSecret) throws GeneralSecurityException { |
1762 SecretKey masterSecret) throws GeneralSecurityException { |
1635 String algorithm = publicKey.getAlgorithm(); |
1763 String algorithm = publicKey.getAlgorithm(); |
1636 Signature sig = null; |
1764 Signature sig = null; |
1637 if (protocolVersion.v >= ProtocolVersion.TLS12.v) { |
1765 if (protocolVersion.useTLS12PlusSpec()) { |
1638 sig = JsseJce.getSignature( |
1766 sig = JsseJce.getSignature( |
1639 preferableSignatureAlgorithm.getAlgorithmName()); |
1767 preferableSignatureAlgorithm.getAlgorithmName()); |
1640 } else { |
1768 } else { |
1641 sig = getSignature(protocolVersion, algorithm); |
1769 sig = getSignature(protocolVersion, algorithm); |
1642 } |
1770 } |
1674 ProtocolVersion protocolVersion, |
1802 ProtocolVersion protocolVersion, |
1675 HandshakeHash handshakeHash, String algorithm, SecretKey masterKey) |
1803 HandshakeHash handshakeHash, String algorithm, SecretKey masterKey) |
1676 throws SignatureException { |
1804 throws SignatureException { |
1677 |
1805 |
1678 if (algorithm.equals("RSA")) { |
1806 if (algorithm.equals("RSA")) { |
1679 if (protocolVersion.v < ProtocolVersion.TLS12.v) { // TLS1.1- |
1807 if (!protocolVersion.useTLS12PlusSpec()) { // TLS1.1- |
1680 MessageDigest md5Clone = handshakeHash.getMD5Clone(); |
1808 MessageDigest md5Clone = handshakeHash.getMD5Clone(); |
1681 MessageDigest shaClone = handshakeHash.getSHAClone(); |
1809 MessageDigest shaClone = handshakeHash.getSHAClone(); |
1682 |
1810 |
1683 if (protocolVersion.v < ProtocolVersion.TLS10.v) { // SSLv3 |
1811 if (!protocolVersion.useTLS10PlusSpec()) { // SSLv3 |
1684 updateDigest(md5Clone, MD5_pad1, MD5_pad2, masterKey); |
1812 updateDigest(md5Clone, MD5_pad1, MD5_pad2, masterKey); |
1685 updateDigest(shaClone, SHA_pad1, SHA_pad2, masterKey); |
1813 updateDigest(shaClone, SHA_pad1, SHA_pad2, masterKey); |
1686 } |
1814 } |
1687 |
1815 |
1688 // The signature must be an instance of RSASignature, need |
1816 // The signature must be an instance of RSASignature, need |
1690 RSASignature.setHashes(sig, md5Clone, shaClone); |
1818 RSASignature.setHashes(sig, md5Clone, shaClone); |
1691 } else { // TLS1.2+ |
1819 } else { // TLS1.2+ |
1692 sig.update(handshakeHash.getAllHandshakeMessages()); |
1820 sig.update(handshakeHash.getAllHandshakeMessages()); |
1693 } |
1821 } |
1694 } else { // DSA, ECDSA |
1822 } else { // DSA, ECDSA |
1695 if (protocolVersion.v < ProtocolVersion.TLS12.v) { // TLS1.1- |
1823 if (!protocolVersion.useTLS12PlusSpec()) { // TLS1.1- |
1696 MessageDigest shaClone = handshakeHash.getSHAClone(); |
1824 MessageDigest shaClone = handshakeHash.getSHAClone(); |
1697 |
1825 |
1698 if (protocolVersion.v < ProtocolVersion.TLS10.v) { // SSLv3 |
1826 if (!protocolVersion.useTLS10PlusSpec()) { // SSLv3 |
1699 updateDigest(shaClone, SHA_pad1, SHA_pad2, masterKey); |
1827 updateDigest(shaClone, SHA_pad1, SHA_pad2, masterKey); |
1700 } |
1828 } |
1701 |
1829 |
1702 sig.update(shaClone.digest()); |
1830 sig.update(shaClone.digest()); |
1703 } else { // TLS1.2+ |
1831 } else { // TLS1.2+ |
1809 |
1937 |
1810 @Override |
1938 @Override |
1811 int messageLength() { |
1939 int messageLength() { |
1812 int temp = 2; |
1940 int temp = 2; |
1813 |
1941 |
1814 if (protocolVersion.v >= ProtocolVersion.TLS12.v) { |
1942 if (protocolVersion.useTLS12PlusSpec()) { |
1815 temp += SignatureAndHashAlgorithm.sizeInRecord(); |
1943 temp += SignatureAndHashAlgorithm.sizeInRecord(); |
1816 } |
1944 } |
1817 |
1945 |
1818 return temp + signature.length; |
1946 return temp + signature.length; |
1819 } |
1947 } |
1820 |
1948 |
1821 @Override |
1949 @Override |
1822 void send(HandshakeOutStream s) throws IOException { |
1950 void send(HandshakeOutStream s) throws IOException { |
1823 if (protocolVersion.v >= ProtocolVersion.TLS12.v) { |
1951 if (protocolVersion.useTLS12PlusSpec()) { |
1824 s.putInt8(preferableSignatureAlgorithm.getHashValue()); |
1952 s.putInt8(preferableSignatureAlgorithm.getHashValue()); |
1825 s.putInt8(preferableSignatureAlgorithm.getSignatureValue()); |
1953 s.putInt8(preferableSignatureAlgorithm.getSignatureValue()); |
1826 } |
1954 } |
1827 |
1955 |
1828 s.putBytes16(signature); |
1956 s.putBytes16(signature); |
1897 */ |
2025 */ |
1898 Finished(ProtocolVersion protocolVersion, HandshakeInStream input, |
2026 Finished(ProtocolVersion protocolVersion, HandshakeInStream input, |
1899 CipherSuite cipherSuite) throws IOException { |
2027 CipherSuite cipherSuite) throws IOException { |
1900 this.protocolVersion = protocolVersion; |
2028 this.protocolVersion = protocolVersion; |
1901 this.cipherSuite = cipherSuite; |
2029 this.cipherSuite = cipherSuite; |
1902 int msgLen = (protocolVersion.v >= ProtocolVersion.TLS10.v) ? 12 : 36; |
2030 int msgLen = protocolVersion.useTLS10PlusSpec() ? 12 : 36; |
1903 verifyData = new byte[msgLen]; |
2031 verifyData = new byte[msgLen]; |
1904 input.read(verifyData); |
2032 input.read(verifyData); |
1905 } |
2033 } |
1906 |
2034 |
1907 /* |
2035 /* |
1930 tlsLabel = "server finished"; |
2058 tlsLabel = "server finished"; |
1931 } else { |
2059 } else { |
1932 throw new RuntimeException("Invalid sender: " + sender); |
2060 throw new RuntimeException("Invalid sender: " + sender); |
1933 } |
2061 } |
1934 |
2062 |
1935 if (protocolVersion.v >= ProtocolVersion.TLS10.v) { |
2063 if (protocolVersion.useTLS10PlusSpec()) { |
1936 // TLS 1.0+ |
2064 // TLS 1.0+ |
1937 try { |
2065 try { |
1938 byte [] seed; |
2066 byte [] seed; |
1939 String prfAlg; |
2067 String prfAlg; |
1940 PRF prf; |
2068 PRF prf; |
1941 |
2069 |
1942 // Get the KeyGenerator alg and calculate the seed. |
2070 // Get the KeyGenerator alg and calculate the seed. |
1943 if (protocolVersion.v >= ProtocolVersion.TLS12.v) { |
2071 if (protocolVersion.useTLS12PlusSpec()) { |
1944 // TLS 1.2 |
2072 // TLS 1.2+ or DTLS 1.2+ |
1945 seed = handshakeHash.getFinishedHash(); |
2073 seed = handshakeHash.getFinishedHash(); |
1946 |
2074 |
1947 prfAlg = "SunTls12Prf"; |
2075 prfAlg = "SunTls12Prf"; |
1948 prf = cipherSuite.prfAlg; |
2076 prf = cipherSuite.prfAlg; |
1949 } else { |
2077 } else { |
1950 // TLS 1.0/1.1 |
2078 // TLS 1.0/1.1, DTLS 1.0 |
1951 MessageDigest md5Clone = handshakeHash.getMD5Clone(); |
2079 MessageDigest md5Clone = handshakeHash.getMD5Clone(); |
1952 MessageDigest shaClone = handshakeHash.getSHAClone(); |
2080 MessageDigest shaClone = handshakeHash.getSHAClone(); |
1953 seed = new byte[36]; |
2081 seed = new byte[36]; |
1954 md5Clone.digest(seed, 0, 16); |
2082 md5Clone.digest(seed, 0, 16); |
1955 shaClone.digest(seed, 16, 20); |
2083 shaClone.digest(seed, 16, 20); |