173 |
173 |
174 ContentType ct = ContentType.valueOf(plaintext.contentType); |
174 ContentType ct = ContentType.valueOf(plaintext.contentType); |
175 if (ct == null) { |
175 if (ct == null) { |
176 fatal(Alert.UNEXPECTED_MESSAGE, |
176 fatal(Alert.UNEXPECTED_MESSAGE, |
177 "Unknown content type: " + plaintext.contentType); |
177 "Unknown content type: " + plaintext.contentType); |
178 return; // make compiler happy |
178 return; |
179 } |
179 } |
180 |
180 |
181 switch (ct) { |
181 switch (ct) { |
182 case HANDSHAKE: |
182 case HANDSHAKE: |
|
183 byte type = HandshakeContext.getHandshakeType(this, |
|
184 plaintext); |
183 if (handshakeContext == null) { |
185 if (handshakeContext == null) { |
184 handshakeContext = sslConfig.isClientMode ? |
186 if (type == SSLHandshake.KEY_UPDATE.id) { |
185 new ClientHandshakeContext(sslContext, this) : |
187 handshakeContext = new PostHandshakeContext(this); |
186 new ServerHandshakeContext(sslContext, this); |
188 } else { |
187 outputRecord.initHandshaker(); |
189 handshakeContext = sslConfig.isClientMode ? |
|
190 new ClientHandshakeContext(sslContext, this) : |
|
191 new ServerHandshakeContext(sslContext, this); |
|
192 outputRecord.initHandshaker(); |
|
193 } |
188 } |
194 } |
189 handshakeContext.dispatch(plaintext); |
195 handshakeContext.dispatch(type, plaintext); |
190 break; |
196 break; |
191 case ALERT: |
197 case ALERT: |
192 Alert.alertConsumer.consume(this, plaintext.fragment); |
198 Alert.alertConsumer.consume(this, plaintext.fragment); |
193 break; |
199 break; |
194 default: |
200 default: |
207 throw new IllegalStateException("Client/Server mode not yet set."); |
213 throw new IllegalStateException("Client/Server mode not yet set."); |
208 } |
214 } |
209 |
215 |
210 // initialize the handshaker if necessary |
216 // initialize the handshaker if necessary |
211 if (handshakeContext == null) { |
217 if (handshakeContext == null) { |
212 handshakeContext = sslConfig.isClientMode ? |
218 // TLS1.3 post-handshake |
213 new ClientHandshakeContext(sslContext, this) : |
219 if (isNegotiated && protocolVersion.useTLS13PlusSpec()) { |
214 new ServerHandshakeContext(sslContext, this); |
220 handshakeContext = new PostHandshakeContext(this); |
215 outputRecord.initHandshaker(); |
221 } else { |
|
222 handshakeContext = sslConfig.isClientMode ? |
|
223 new ClientHandshakeContext(sslContext, this) : |
|
224 new ServerHandshakeContext(sslContext, this); |
|
225 outputRecord.initHandshaker(); |
|
226 } |
216 } |
227 } |
217 |
228 |
218 // kickstart the handshake if needed |
229 // kickstart the handshake if needed |
219 // |
230 // |
220 // Need no kickstart message on server side unless the connection |
231 // Need no kickstart message on server side unless the connection |
221 // has been estabilished. |
232 // has been established. |
222 if(isNegotiated || sslConfig.isClientMode) { |
233 if(isNegotiated || sslConfig.isClientMode) { |
223 handshakeContext.kickstart(); |
234 handshakeContext.kickstart(); |
224 } |
235 } |
225 } |
236 } |
226 |
237 |
227 void keyUpdate() throws IOException { |
238 void keyUpdate() throws IOException { |
228 // TODO: TLS 1.3 |
|
229 kickstart(); |
239 kickstart(); |
230 } |
240 } |
231 |
241 |
232 // Note: close_notify is delivered as awarning alert. |
242 final static byte PRE = 1; |
|
243 final static byte POST = 2; |
|
244 |
|
245 HandshakeContext getHandshakeContext(byte type) { |
|
246 if (handshakeContext == null) { |
|
247 return null; |
|
248 } |
|
249 |
|
250 if (type == PRE && |
|
251 (handshakeContext instanceof ClientHandshakeContext || |
|
252 handshakeContext instanceof ServerHandshakeContext)) { |
|
253 return handshakeContext; |
|
254 } |
|
255 |
|
256 if (type == POST && handshakeContext instanceof PostHandshakeContext) { |
|
257 return handshakeContext; |
|
258 } |
|
259 |
|
260 return null; |
|
261 } |
|
262 |
|
263 // Note: close_notify is delivered as a warning alert. |
233 void warning(Alert alert) { |
264 void warning(Alert alert) { |
234 // For initial handshaking, don't send awarning alert message to peer |
265 // For initial handshaking, don't send a warning alert message to peer |
235 // if handshaker has not started. |
266 // if handshaker has not started. |
236 if (isNegotiated || handshakeContext != null) { |
267 if (isNegotiated || handshakeContext != null) { |
237 try { |
268 try { |
238 outputRecord.encodeAlert(Alert.Level.WARNING.level, alert.id); |
269 outputRecord.encodeAlert(Alert.Level.WARNING.level, alert.id); |
239 } catch (IOException ioe) { |
270 } catch (IOException ioe) { |