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.
73 *
74 * @author David Brownell
75 */
76 public abstract class HandshakeMessage {
77
78 /* Class and subclass dynamic debugging support */
79 public static final Debug debug = Debug.getInstance("ssl");
80
81 // enum HandshakeType:
82 static final byte ht_hello_request = 0; // RFC 5246
83 static final byte ht_client_hello = 1; // RFC 5246
84 static final byte ht_server_hello = 2; // RFC 5246
85 static final byte ht_hello_verify_request = 3; // RFC 6347
86 static final byte ht_new_session_ticket = 4; // RFC 4507
87
88 static final byte ht_certificate = 11; // RFC 5246
89 static final byte ht_server_key_exchange = 12; // RFC 5246
90 static final byte ht_certificate_request = 13; // RFC 5246
91 static final byte ht_server_hello_done = 14; // RFC 5246
92 static final byte ht_certificate_verify = 15; // RFC 5246
93 static final byte ht_client_key_exchange = 16; // RFC 5246
94
95 static final byte ht_finished = 20; // RFC 5246
96 static final byte ht_certificate_url = 21; // RFC 6066
97 static final byte ht_certificate_status = 22; // RFC 6066
98 static final byte ht_supplemental_data = 23; // RFC 4680
99
100 static final byte ht_not_applicable = -1; // N/A
101
113 HandshakeMessage() {
114 }
115
116 /**
117 * Utility method to convert a BigInteger to a byte array in unsigned
118 * format as needed in the handshake messages. BigInteger uses
119 * 2's complement format, i.e. it prepends an extra zero if the MSB
120 * is set. We remove that.
121 */
122 static byte[] toByteArray(BigInteger bi) {
123 byte[] b = bi.toByteArray();
124 if ((b.length > 1) && (b[0] == 0)) {
125 int n = b.length - 1;
126 byte[] newarray = new byte[n];
127 System.arraycopy(b, 1, newarray, 0, n);
128 b = newarray;
129 }
130 return b;
131 }
132
133 private static byte[] genPad(int b, int count) {
134 byte[] padding = new byte[count];
135 Arrays.fill(padding, (byte)b);
136 return padding;
137 }
138
139 /*
140 * Write a handshake message on the (handshake) output stream.
141 * This is just a four byte header followed by the data.
142 *
143 * NOTE that huge messages -- notably, ones with huge cert
144 * chains -- are handled correctly.
145 */
146 final void write(HandshakeOutStream s) throws IOException {
147 int len = messageLength();
148 if (len >= Record.OVERFLOW_OF_INT24) {
149 throw new SSLException("Handshake message too big"
150 + ", type = " + messageType() + ", len = " + len);
151 }
152 s.write(messageType());
|
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.
73 *
74 * @author David Brownell
75 */
76 public abstract class HandshakeMessage {
77
78 /* Class and subclass dynamic debugging support */
79 public static final Debug debug = Debug.getInstance("ssl");
80
81 // enum HandshakeType:
82 //
83 // Please update the isUnsupported() method accordingly if the handshake
84 // types get updated in the future.
85 static final byte ht_hello_request = 0; // RFC 5246
86 static final byte ht_client_hello = 1; // RFC 5246
87 static final byte ht_server_hello = 2; // RFC 5246
88 static final byte ht_hello_verify_request = 3; // RFC 6347
89 static final byte ht_new_session_ticket = 4; // RFC 4507
90
91 static final byte ht_certificate = 11; // RFC 5246
92 static final byte ht_server_key_exchange = 12; // RFC 5246
93 static final byte ht_certificate_request = 13; // RFC 5246
94 static final byte ht_server_hello_done = 14; // RFC 5246
95 static final byte ht_certificate_verify = 15; // RFC 5246
96 static final byte ht_client_key_exchange = 16; // RFC 5246
97
98 static final byte ht_finished = 20; // RFC 5246
99 static final byte ht_certificate_url = 21; // RFC 6066
100 static final byte ht_certificate_status = 22; // RFC 6066
101 static final byte ht_supplemental_data = 23; // RFC 4680
102
103 static final byte ht_not_applicable = -1; // N/A
104
116 HandshakeMessage() {
117 }
118
119 /**
120 * Utility method to convert a BigInteger to a byte array in unsigned
121 * format as needed in the handshake messages. BigInteger uses
122 * 2's complement format, i.e. it prepends an extra zero if the MSB
123 * is set. We remove that.
124 */
125 static byte[] toByteArray(BigInteger bi) {
126 byte[] b = bi.toByteArray();
127 if ((b.length > 1) && (b[0] == 0)) {
128 int n = b.length - 1;
129 byte[] newarray = new byte[n];
130 System.arraycopy(b, 1, newarray, 0, n);
131 b = newarray;
132 }
133 return b;
134 }
135
136 static boolean isUnsupported(byte handshakeType) {
137 return (handshakeType != ht_hello_request) &&
138 (handshakeType != ht_client_hello) &&
139 (handshakeType != ht_server_hello) &&
140 (handshakeType != ht_hello_verify_request) &&
141 (handshakeType != ht_new_session_ticket) &&
142 (handshakeType != ht_certificate) &&
143 (handshakeType != ht_server_key_exchange) &&
144 (handshakeType != ht_certificate_request) &&
145 (handshakeType != ht_server_hello_done) &&
146 (handshakeType != ht_certificate_verify) &&
147 (handshakeType != ht_client_key_exchange) &&
148 (handshakeType != ht_finished) &&
149 (handshakeType != ht_certificate_url) &&
150 (handshakeType != ht_certificate_status) &&
151 (handshakeType != ht_supplemental_data);
152 }
153
154 private static byte[] genPad(int b, int count) {
155 byte[] padding = new byte[count];
156 Arrays.fill(padding, (byte)b);
157 return padding;
158 }
159
160 /*
161 * Write a handshake message on the (handshake) output stream.
162 * This is just a four byte header followed by the data.
163 *
164 * NOTE that huge messages -- notably, ones with huge cert
165 * chains -- are handled correctly.
166 */
167 final void write(HandshakeOutStream s) throws IOException {
168 int len = messageLength();
169 if (len >= Record.OVERFLOW_OF_INT24) {
170 throw new SSLException("Handshake message too big"
171 + ", type = " + messageType() + ", len = " + len);
172 }
173 s.write(messageType());
|