57 * unwrap() ... ServerHello/Certificate
58 * wrap() ... ClientKeyExchange
59 * wrap() ... ChangeCipherSpec
60 * wrap() ... Finished
61 * ... unwrap() ClientKeyExchange
62 * ... unwrap() ChangeCipherSpec
63 * ... unwrap() Finished
64 * ... wrap() ChangeCipherSpec
65 * ... wrap() Finished
66 * unwrap() ... ChangeCipherSpec
67 * unwrap() ... Finished
68 */
69
70 import javax.net.ssl.*;
71 import javax.net.ssl.SSLEngineResult.*;
72 import java.io.*;
73 import java.security.*;
74 import java.nio.*;
75 import java.util.List;
76 import java.util.ArrayList;
77 import sun.security.ssl.ProtocolVersion;
78
79 public class LengthCheckTest {
80
81 /*
82 * Enables logging of the SSLEngine operations.
83 */
84 private static final boolean logging = true;
85
86 /*
87 * Enables the JSSE system debugging system property:
88 *
89 * -Djavax.net.debug=all
90 *
91 * This gives a lot of low-level information about operations underway,
92 * including specific handshake messages, and might be best examined
93 * after gaining some familiarity with this application.
94 */
95 private static final boolean debug = false;
96 private static final boolean dumpBufs = true;
97
138
139 private static final int TLS_HS_HELLO_REQUEST = 0x00;
140 private static final int TLS_HS_CLIENT_HELLO = 0x01;
141 private static final int TLS_HS_SERVER_HELLO = 0x02;
142 private static final int TLS_HS_CERTIFICATE = 0x0B;
143 private static final int TLS_HS_SERVER_KEY_EXCHG = 0x0C;
144 private static final int TLS_HS_CERT_REQUEST = 0x0D;
145 private static final int TLS_HS_SERVER_HELLO_DONE = 0x0E;
146 private static final int TLS_HS_CERT_VERIFY = 0x0F;
147 private static final int TLS_HS_CLIENT_KEY_EXCHG = 0x10;
148 private static final int TLS_HS_FINISHED = 0x14;
149
150 // We're not going to define all the alert types in TLS, just
151 // the ones we think we'll need to reference by name.
152 private static final int TLS_ALERT_LVL_WARNING = 0x01;
153 private static final int TLS_ALERT_LVL_FATAL = 0x02;
154
155 private static final int TLS_ALERT_UNEXPECTED_MSG = 0x0A;
156 private static final int TLS_ALERT_HANDSHAKE_FAILURE = 0x28;
157 private static final int TLS_ALERT_INTERNAL_ERROR = 0x50;
158
159 public interface HandshakeTest {
160 void execTest() throws Exception;
161 }
162
163 public final HandshakeTest servSendLongID = new HandshakeTest() {
164 @Override
165 public void execTest() throws Exception {
166 boolean gotException = false;
167 SSLEngineResult clientResult; // results from client's last op
168 SSLEngineResult serverResult; // results from server's last op
169
170 log("\n==== Test: Client receives 64-byte session ID ====");
171
172 // Send Client Hello
173 clientResult = clientEngine.wrap(clientOut, cTOs);
174 log("client wrap: ", clientResult);
175 runDelegatedTasks(clientResult, clientEngine);
176 cTOs.flip();
177 dumpByteBuffer("CLIENT-TO-SERVER", cTOs);
251
252 // Send Client Hello
253 ByteBuffer evilClientHello = createEvilClientHello(64);
254 dumpByteBuffer("CLIENT-TO-SERVER", evilClientHello);
255
256 try {
257 // Server consumes Client Hello
258 serverResult = serverEngine.unwrap(evilClientHello, serverIn);
259 log("server unwrap: ", serverResult);
260 runDelegatedTasks(serverResult, serverEngine);
261 evilClientHello.compact();
262
263 // Under normal circumstances this should be a ServerHello
264 // But should throw an exception instead due to the invalid
265 // session ID.
266 serverResult = serverEngine.wrap(serverOut, sTOc);
267 log("server wrap: ", serverResult);
268 runDelegatedTasks(serverResult, serverEngine);
269 sTOc.flip();
270 dumpByteBuffer("SERVER-TO-CLIENT", sTOc);
271 } catch (SSLProtocolException ssle) {
272 log("Received expected SSLProtocolException: " + ssle);
273 gotException = true;
274 }
275
276 // We expect to see the server generate an alert here
277 serverResult = serverEngine.wrap(serverOut, sTOc);
278 log("server wrap: ", serverResult);
279 runDelegatedTasks(serverResult, serverEngine);
280 sTOc.flip();
281 dumpByteBuffer("SERVER-TO-CLIENT", sTOc);
282
283 // At this point we can verify that both an exception
284 // was thrown and the proper action (a TLS alert) was
285 // sent back to the client.
286 if (gotException == false ||
287 !isTlsMessage(sTOc, TLS_RECTYPE_ALERT, TLS_ALERT_LVL_FATAL,
288 TLS_ALERT_UNEXPECTED_MSG)) {
289 throw new SSLException(
290 "Server failed to throw Alert:fatal:internal_error");
291 }
292 }
293 };
294
295
296 /*
297 * Main entry point for this test.
298 */
299 public static void main(String args[]) throws Exception {
300 List<LengthCheckTest> ccsTests = new ArrayList<>();
301
302 if (debug) {
303 System.setProperty("javax.net.debug", "ssl");
304 }
305
306 ccsTests.add(new LengthCheckTest("ServSendLongID"));
307 ccsTests.add(new LengthCheckTest("ClientSendLongID"));
308
766 }
767
768 /**
769 * Hex-dumps a ByteBuffer to stdout.
770 */
771 private static void dumpByteBuffer(String header, ByteBuffer bBuf) {
772 if (dumpBufs == false) {
773 return;
774 }
775
776 int bufLen = bBuf.remaining();
777 if (bufLen > 0) {
778 bBuf.mark();
779
780 // We expect the position of the buffer to be at the
781 // beginning of a TLS record. Get the type, version and length.
782 int type = Byte.toUnsignedInt(bBuf.get());
783 int ver_major = Byte.toUnsignedInt(bBuf.get());
784 int ver_minor = Byte.toUnsignedInt(bBuf.get());
785 int recLen = Short.toUnsignedInt(bBuf.getShort());
786 ProtocolVersion pv = ProtocolVersion.valueOf(ver_major, ver_minor);
787
788 log("===== " + header + " (" + tlsRecType(type) + " / " +
789 pv + " / " + bufLen + " bytes) =====");
790 bBuf.reset();
791 for (int i = 0; i < bufLen; i++) {
792 if (i != 0 && i % 16 == 0) {
793 System.out.print("\n");
794 }
795 System.out.format("%02X ", bBuf.get(i));
796 }
797 log("\n===============================================");
798 bBuf.reset();
799 }
800 }
801
802 private static String tlsRecType(int type) {
803 switch (type) {
804 case 20:
805 return "Change Cipher Spec";
806 case 21:
807 return "Alert";
808 case 22:
809 return "Handshake";
|
57 * unwrap() ... ServerHello/Certificate
58 * wrap() ... ClientKeyExchange
59 * wrap() ... ChangeCipherSpec
60 * wrap() ... Finished
61 * ... unwrap() ClientKeyExchange
62 * ... unwrap() ChangeCipherSpec
63 * ... unwrap() Finished
64 * ... wrap() ChangeCipherSpec
65 * ... wrap() Finished
66 * unwrap() ... ChangeCipherSpec
67 * unwrap() ... Finished
68 */
69
70 import javax.net.ssl.*;
71 import javax.net.ssl.SSLEngineResult.*;
72 import java.io.*;
73 import java.security.*;
74 import java.nio.*;
75 import java.util.List;
76 import java.util.ArrayList;
77
78 public class LengthCheckTest {
79
80 /*
81 * Enables logging of the SSLEngine operations.
82 */
83 private static final boolean logging = true;
84
85 /*
86 * Enables the JSSE system debugging system property:
87 *
88 * -Djavax.net.debug=all
89 *
90 * This gives a lot of low-level information about operations underway,
91 * including specific handshake messages, and might be best examined
92 * after gaining some familiarity with this application.
93 */
94 private static final boolean debug = false;
95 private static final boolean dumpBufs = true;
96
137
138 private static final int TLS_HS_HELLO_REQUEST = 0x00;
139 private static final int TLS_HS_CLIENT_HELLO = 0x01;
140 private static final int TLS_HS_SERVER_HELLO = 0x02;
141 private static final int TLS_HS_CERTIFICATE = 0x0B;
142 private static final int TLS_HS_SERVER_KEY_EXCHG = 0x0C;
143 private static final int TLS_HS_CERT_REQUEST = 0x0D;
144 private static final int TLS_HS_SERVER_HELLO_DONE = 0x0E;
145 private static final int TLS_HS_CERT_VERIFY = 0x0F;
146 private static final int TLS_HS_CLIENT_KEY_EXCHG = 0x10;
147 private static final int TLS_HS_FINISHED = 0x14;
148
149 // We're not going to define all the alert types in TLS, just
150 // the ones we think we'll need to reference by name.
151 private static final int TLS_ALERT_LVL_WARNING = 0x01;
152 private static final int TLS_ALERT_LVL_FATAL = 0x02;
153
154 private static final int TLS_ALERT_UNEXPECTED_MSG = 0x0A;
155 private static final int TLS_ALERT_HANDSHAKE_FAILURE = 0x28;
156 private static final int TLS_ALERT_INTERNAL_ERROR = 0x50;
157 private static final int TLS_ALERT_ILLEGAL_PARAMETER = 0x2F;
158
159 public interface HandshakeTest {
160 void execTest() throws Exception;
161 }
162
163 public final HandshakeTest servSendLongID = new HandshakeTest() {
164 @Override
165 public void execTest() throws Exception {
166 boolean gotException = false;
167 SSLEngineResult clientResult; // results from client's last op
168 SSLEngineResult serverResult; // results from server's last op
169
170 log("\n==== Test: Client receives 64-byte session ID ====");
171
172 // Send Client Hello
173 clientResult = clientEngine.wrap(clientOut, cTOs);
174 log("client wrap: ", clientResult);
175 runDelegatedTasks(clientResult, clientEngine);
176 cTOs.flip();
177 dumpByteBuffer("CLIENT-TO-SERVER", cTOs);
251
252 // Send Client Hello
253 ByteBuffer evilClientHello = createEvilClientHello(64);
254 dumpByteBuffer("CLIENT-TO-SERVER", evilClientHello);
255
256 try {
257 // Server consumes Client Hello
258 serverResult = serverEngine.unwrap(evilClientHello, serverIn);
259 log("server unwrap: ", serverResult);
260 runDelegatedTasks(serverResult, serverEngine);
261 evilClientHello.compact();
262
263 // Under normal circumstances this should be a ServerHello
264 // But should throw an exception instead due to the invalid
265 // session ID.
266 serverResult = serverEngine.wrap(serverOut, sTOc);
267 log("server wrap: ", serverResult);
268 runDelegatedTasks(serverResult, serverEngine);
269 sTOc.flip();
270 dumpByteBuffer("SERVER-TO-CLIENT", sTOc);
271
272 // We expect to see the server generate an alert here
273 serverResult = serverEngine.wrap(serverOut, sTOc);
274 log("server wrap: ", serverResult);
275 runDelegatedTasks(serverResult, serverEngine);
276 sTOc.flip();
277 dumpByteBuffer("SERVER-TO-CLIENT", sTOc);
278 } catch (SSLProtocolException ssle) {
279 log("Received expected SSLProtocolException: " + ssle);
280 gotException = true;
281 }
282
283 // At this point we can verify that both an exception
284 // was thrown and the proper action (a TLS alert) was
285 // sent back to the client.
286 if (gotException == false ||
287 !isTlsMessage(sTOc, TLS_RECTYPE_ALERT, TLS_ALERT_LVL_FATAL,
288 TLS_ALERT_ILLEGAL_PARAMETER)) {
289 throw new SSLException(
290 "Server failed to throw Alert:fatal:internal_error");
291 }
292 }
293 };
294
295
296 /*
297 * Main entry point for this test.
298 */
299 public static void main(String args[]) throws Exception {
300 List<LengthCheckTest> ccsTests = new ArrayList<>();
301
302 if (debug) {
303 System.setProperty("javax.net.debug", "ssl");
304 }
305
306 ccsTests.add(new LengthCheckTest("ServSendLongID"));
307 ccsTests.add(new LengthCheckTest("ClientSendLongID"));
308
766 }
767
768 /**
769 * Hex-dumps a ByteBuffer to stdout.
770 */
771 private static void dumpByteBuffer(String header, ByteBuffer bBuf) {
772 if (dumpBufs == false) {
773 return;
774 }
775
776 int bufLen = bBuf.remaining();
777 if (bufLen > 0) {
778 bBuf.mark();
779
780 // We expect the position of the buffer to be at the
781 // beginning of a TLS record. Get the type, version and length.
782 int type = Byte.toUnsignedInt(bBuf.get());
783 int ver_major = Byte.toUnsignedInt(bBuf.get());
784 int ver_minor = Byte.toUnsignedInt(bBuf.get());
785 int recLen = Short.toUnsignedInt(bBuf.getShort());
786
787 log("===== " + header + " (" + tlsRecType(type) + " / " +
788 ver_major + "." + ver_minor + " / " + bufLen + " bytes) =====");
789 bBuf.reset();
790 for (int i = 0; i < bufLen; i++) {
791 if (i != 0 && i % 16 == 0) {
792 System.out.print("\n");
793 }
794 System.out.format("%02X ", bBuf.get(i));
795 }
796 log("\n===============================================");
797 bBuf.reset();
798 }
799 }
800
801 private static String tlsRecType(int type) {
802 switch (type) {
803 case 20:
804 return "Change Cipher Spec";
805 case 21:
806 return "Alert";
807 case 22:
808 return "Handshake";
|