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

Print this page
8167680 DTLS implementation bugs

*** 1,7 **** /* ! * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this --- 1,7 ---- /* ! * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this
*** 992,1011 **** fatal(Alerts.alert_unexpected_message, ioe); } // plainText should never be null for TLS protocols HandshakeStatus hsStatus = null; ! if (!isDTLS || plainText != null) { hsStatus = processInputRecord(plainText, appData, offset, length); } if (hsStatus == null) { hsStatus = getHSStatus(null); } if (plainText == null) { ! plainText = new Plaintext(); } plainText.handshakeStatus = hsStatus; return plainText; } --- 992,1026 ---- fatal(Alerts.alert_unexpected_message, ioe); } // plainText should never be null for TLS protocols HandshakeStatus hsStatus = null; ! if (plainText == Plaintext.PLAINTEXT_NULL) { ! // Only happens for DTLS protocols. ! // ! // Received a retransmitted flight, and need to retransmit the ! // previous delivered handshake flight messages. ! if (enableRetransmissions) { ! if (debug != null && Debug.isOn("verbose")) { ! Debug.log( ! "Retransmit the previous handshake flight messages."); ! } ! ! synchronized (this) { ! outputRecord.launchRetransmission(); ! } ! } // Otherwise, discard the retransmitted flight. ! } else if (!isDTLS || plainText != null) { hsStatus = processInputRecord(plainText, appData, offset, length); } if (hsStatus == null) { hsStatus = getHSStatus(null); } if (plainText == null) { ! plainText = Plaintext.PLAINTEXT_NULL; } plainText.handshakeStatus = hsStatus; return plainText; }
*** 1376,1386 **** Ciphertext ciphertext = null; try { // Acquire the buffered to-be-delivered records or retransmissions. // // May have buffered records, or need retransmission if handshaking. ! if (!outputRecord.isEmpty() || (handshaker != null)) { ciphertext = outputRecord.acquireCiphertext(netData); } if ((ciphertext == null) && (appData != null)) { ciphertext = outputRecord.encode( --- 1391,1402 ---- Ciphertext ciphertext = null; try { // Acquire the buffered to-be-delivered records or retransmissions. // // May have buffered records, or need retransmission if handshaking. ! if (!outputRecord.isEmpty() || ! (enableRetransmissions && handshaker != null)) { ciphertext = outputRecord.acquireCiphertext(netData); } if ((ciphertext == null) && (appData != null)) { ciphertext = outputRecord.encode(
*** 1401,1417 **** return Ciphertext.CIPHERTEXT_NULL; } HandshakeStatus hsStatus = null; Ciphertext.RecordType recordType = ciphertext.recordType; ! if ((handshaker != null) && ! (recordType.contentType == Record.ct_handshake) && (recordType.handshakeType == HandshakeMessage.ht_finished) && ! handshaker.isDone() && outputRecord.isEmpty()) { hsStatus = finishHandshake(); connectionState = cs_DATA; } // Otherwise, the followed call to getHSStatus() will help. /* * We only need to check the sequence number state for * non-handshaking record. --- 1417,1456 ---- return Ciphertext.CIPHERTEXT_NULL; } HandshakeStatus hsStatus = null; Ciphertext.RecordType recordType = ciphertext.recordType; ! if ((recordType.contentType == Record.ct_handshake) && (recordType.handshakeType == HandshakeMessage.ht_finished) && ! outputRecord.isEmpty()) { + if (handshaker == null) { + hsStatus = HandshakeStatus.FINISHED; + } else if (handshaker.isDone()) { hsStatus = finishHandshake(); connectionState = cs_DATA; + + // Retransmit the last flight twice. + // + // The application data transactions may begin immediately + // after the last flight. If the last flight get lost, the + // application data may be discarded accordingly. As could + // be an issue for some applications. This impact can be + // mitigated by sending the last fligth twice. + if (isDTLS && enableRetransmissions) { + if (debug != null && Debug.isOn("verbose")) { + Debug.log( + "Retransmit the last flight messages."); + } + + synchronized (this) { + outputRecord.launchRetransmission(); + } + + hsStatus = HandshakeStatus.NEED_WRAP; + } + } } // Otherwise, the followed call to getHSStatus() will help. /* * We only need to check the sequence number state for * non-handshaking record.