1 /*
2 * Copyright (c) 2003, 2015, Oracle and/or its affiliates. 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. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
977 } catch (BadPaddingException e) {
978 /*
979 * The basic SSLv3 record protection involves (optional)
980 * encryption for privacy, and an integrity check ensuring
981 * data origin authentication. We do them both here, and
982 * throw a fatal alert if the integrity check fails.
983 */
984 byte alertType = (connectionState != cs_DATA) ?
985 Alerts.alert_handshake_failure :
986 Alerts.alert_bad_record_mac;
987 fatal(alertType, e.getMessage(), e);
988 } catch (SSLHandshakeException she) {
989 // may be record sequence number overflow
990 fatal(Alerts.alert_handshake_failure, she);
991 } catch (IOException ioe) {
992 fatal(Alerts.alert_unexpected_message, ioe);
993 }
994
995 // plainText should never be null for TLS protocols
996 HandshakeStatus hsStatus = null;
997 if (!isDTLS || plainText != null) {
998 hsStatus = processInputRecord(plainText, appData, offset, length);
999 }
1000
1001 if (hsStatus == null) {
1002 hsStatus = getHSStatus(null);
1003 }
1004
1005 if (plainText == null) {
1006 plainText = new Plaintext();
1007 }
1008 plainText.handshakeStatus = hsStatus;
1009
1010 return plainText;
1011 }
1012
1013 /*
1014 * Process the record.
1015 */
1016 private synchronized HandshakeStatus processInputRecord(
1017 Plaintext plainText,
1018 ByteBuffer[] appData, int offset, int length) throws IOException {
1019
1020 HandshakeStatus hsStatus = null;
1021 switch (plainText.contentType) {
1022 case Record.ct_handshake:
1023 /*
1024 * Handshake messages always go to a pending session
1025 * handshaker ... if there isn't one, create one. This
1026 * must work asynchronously, for renegotiation.
1361 int deltaApp = appRemains;
1362 for (int i = offset; i < offset + length; i++) {
1363 deltaApp -= appData[i].remaining();
1364 }
1365
1366 return new SSLEngineResult(
1367 status, hsStatus, deltaApp, deltaNet, ciphertext.recordSN);
1368 }
1369
1370 /*
1371 * Central point to write/get all of the outgoing data.
1372 */
1373 private Ciphertext writeRecord(ByteBuffer[] appData,
1374 int offset, int length, ByteBuffer netData) throws IOException {
1375
1376 Ciphertext ciphertext = null;
1377 try {
1378 // Acquire the buffered to-be-delivered records or retransmissions.
1379 //
1380 // May have buffered records, or need retransmission if handshaking.
1381 if (!outputRecord.isEmpty() || (handshaker != null)) {
1382 ciphertext = outputRecord.acquireCiphertext(netData);
1383 }
1384
1385 if ((ciphertext == null) && (appData != null)) {
1386 ciphertext = outputRecord.encode(
1387 appData, offset, length, netData);
1388 }
1389 } catch (SSLHandshakeException she) {
1390 // may be record sequence number overflow
1391 fatal(Alerts.alert_handshake_failure, she);
1392
1393 return Ciphertext.CIPHERTEXT_NULL; // make the complier happy
1394 } catch (IOException e) {
1395 fatal(Alerts.alert_unexpected_message, e);
1396
1397 return Ciphertext.CIPHERTEXT_NULL; // make the complier happy
1398 }
1399
1400 if (ciphertext == null) {
1401 return Ciphertext.CIPHERTEXT_NULL;
1402 }
1403
1404 HandshakeStatus hsStatus = null;
1405 Ciphertext.RecordType recordType = ciphertext.recordType;
1406 if ((handshaker != null) &&
1407 (recordType.contentType == Record.ct_handshake) &&
1408 (recordType.handshakeType == HandshakeMessage.ht_finished) &&
1409 handshaker.isDone() && outputRecord.isEmpty()) {
1410
1411 hsStatus = finishHandshake();
1412 connectionState = cs_DATA;
1413 } // Otherwise, the followed call to getHSStatus() will help.
1414
1415 /*
1416 * We only need to check the sequence number state for
1417 * non-handshaking record.
1418 *
1419 * Note that in order to maintain the handshake status
1420 * properly, we check the sequence number after the last
1421 * record writing process. As we request renegotiation
1422 * or close the connection for wrapped sequence number
1423 * when there is enough sequence number space left to
1424 * handle a few more records, so the sequence number
1425 * of the last record cannot be wrapped.
1426 */
1427 hsStatus = getHSStatus(hsStatus);
1428 if (connectionState < cs_ERROR && !isOutboundDone() &&
1429 (hsStatus == HandshakeStatus.NOT_HANDSHAKING) &&
1430 (outputRecord.seqNumIsHuge())) {
1431 /*
1432 * Ask for renegotiation when need to renew sequence number.
|
1 /*
2 * Copyright (c) 2003, 2016, Oracle and/or its affiliates. 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. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
977 } catch (BadPaddingException e) {
978 /*
979 * The basic SSLv3 record protection involves (optional)
980 * encryption for privacy, and an integrity check ensuring
981 * data origin authentication. We do them both here, and
982 * throw a fatal alert if the integrity check fails.
983 */
984 byte alertType = (connectionState != cs_DATA) ?
985 Alerts.alert_handshake_failure :
986 Alerts.alert_bad_record_mac;
987 fatal(alertType, e.getMessage(), e);
988 } catch (SSLHandshakeException she) {
989 // may be record sequence number overflow
990 fatal(Alerts.alert_handshake_failure, she);
991 } catch (IOException ioe) {
992 fatal(Alerts.alert_unexpected_message, ioe);
993 }
994
995 // plainText should never be null for TLS protocols
996 HandshakeStatus hsStatus = null;
997 if (plainText == Plaintext.PLAINTEXT_NULL) {
998 // Only happens for DTLS protocols.
999 //
1000 // Received a retransmitted flight, and need to retransmit the
1001 // previous delivered handshake flight messages.
1002 if (enableRetransmissions) {
1003 if (debug != null && Debug.isOn("verbose")) {
1004 Debug.log(
1005 "Retransmit the previous handshake flight messages.");
1006 }
1007
1008 synchronized (this) {
1009 outputRecord.launchRetransmission();
1010 }
1011 } // Otherwise, discard the retransmitted flight.
1012 } else if (!isDTLS || plainText != null) {
1013 hsStatus = processInputRecord(plainText, appData, offset, length);
1014 }
1015
1016 if (hsStatus == null) {
1017 hsStatus = getHSStatus(null);
1018 }
1019
1020 if (plainText == null) {
1021 plainText = Plaintext.PLAINTEXT_NULL;
1022 }
1023 plainText.handshakeStatus = hsStatus;
1024
1025 return plainText;
1026 }
1027
1028 /*
1029 * Process the record.
1030 */
1031 private synchronized HandshakeStatus processInputRecord(
1032 Plaintext plainText,
1033 ByteBuffer[] appData, int offset, int length) throws IOException {
1034
1035 HandshakeStatus hsStatus = null;
1036 switch (plainText.contentType) {
1037 case Record.ct_handshake:
1038 /*
1039 * Handshake messages always go to a pending session
1040 * handshaker ... if there isn't one, create one. This
1041 * must work asynchronously, for renegotiation.
1376 int deltaApp = appRemains;
1377 for (int i = offset; i < offset + length; i++) {
1378 deltaApp -= appData[i].remaining();
1379 }
1380
1381 return new SSLEngineResult(
1382 status, hsStatus, deltaApp, deltaNet, ciphertext.recordSN);
1383 }
1384
1385 /*
1386 * Central point to write/get all of the outgoing data.
1387 */
1388 private Ciphertext writeRecord(ByteBuffer[] appData,
1389 int offset, int length, ByteBuffer netData) throws IOException {
1390
1391 Ciphertext ciphertext = null;
1392 try {
1393 // Acquire the buffered to-be-delivered records or retransmissions.
1394 //
1395 // May have buffered records, or need retransmission if handshaking.
1396 if (!outputRecord.isEmpty() ||
1397 (enableRetransmissions && handshaker != null)) {
1398 ciphertext = outputRecord.acquireCiphertext(netData);
1399 }
1400
1401 if ((ciphertext == null) && (appData != null)) {
1402 ciphertext = outputRecord.encode(
1403 appData, offset, length, netData);
1404 }
1405 } catch (SSLHandshakeException she) {
1406 // may be record sequence number overflow
1407 fatal(Alerts.alert_handshake_failure, she);
1408
1409 return Ciphertext.CIPHERTEXT_NULL; // make the complier happy
1410 } catch (IOException e) {
1411 fatal(Alerts.alert_unexpected_message, e);
1412
1413 return Ciphertext.CIPHERTEXT_NULL; // make the complier happy
1414 }
1415
1416 if (ciphertext == null) {
1417 return Ciphertext.CIPHERTEXT_NULL;
1418 }
1419
1420 HandshakeStatus hsStatus = null;
1421 Ciphertext.RecordType recordType = ciphertext.recordType;
1422 if ((recordType.contentType == Record.ct_handshake) &&
1423 (recordType.handshakeType == HandshakeMessage.ht_finished) &&
1424 outputRecord.isEmpty()) {
1425
1426 if (handshaker == null) {
1427 hsStatus = HandshakeStatus.FINISHED;
1428 } else if (handshaker.isDone()) {
1429 hsStatus = finishHandshake();
1430 connectionState = cs_DATA;
1431
1432 // Retransmit the last flight twice.
1433 //
1434 // The application data transactions may begin immediately
1435 // after the last flight. If the last flight get lost, the
1436 // application data may be discarded accordingly. As could
1437 // be an issue for some applications. This impact can be
1438 // mitigated by sending the last fligth twice.
1439 if (isDTLS && enableRetransmissions) {
1440 if (debug != null && Debug.isOn("verbose")) {
1441 Debug.log(
1442 "Retransmit the last flight messages.");
1443 }
1444
1445 synchronized (this) {
1446 outputRecord.launchRetransmission();
1447 }
1448
1449 hsStatus = HandshakeStatus.NEED_WRAP;
1450 }
1451 }
1452 } // Otherwise, the followed call to getHSStatus() will help.
1453
1454 /*
1455 * We only need to check the sequence number state for
1456 * non-handshaking record.
1457 *
1458 * Note that in order to maintain the handshake status
1459 * properly, we check the sequence number after the last
1460 * record writing process. As we request renegotiation
1461 * or close the connection for wrapped sequence number
1462 * when there is enough sequence number space left to
1463 * handle a few more records, so the sequence number
1464 * of the last record cannot be wrapped.
1465 */
1466 hsStatus = getHSStatus(hsStatus);
1467 if (connectionState < cs_ERROR && !isOutboundDone() &&
1468 (hsStatus == HandshakeStatus.NOT_HANDSHAKING) &&
1469 (outputRecord.seqNumIsHuge())) {
1470 /*
1471 * Ask for renegotiation when need to renew sequence number.
|