249 if (SSLLogger.isOn && SSLLogger.isOn("session")) { |
256 if (SSLLogger.isOn && SSLLogger.isOn("session")) { |
250 SSLLogger.finest("Session initialized: " + this); |
257 SSLLogger.finest("Session initialized: " + this); |
251 } |
258 } |
252 } |
259 } |
253 |
260 |
|
261 /** |
|
262 * < 2 bytes > protocolVersion |
|
263 * < 2 bytes > cipherSuite |
|
264 * < 2 bytes > localSupportedSignAlgs entries |
|
265 * < 2 bytes per entries > localSupportedSignAlgs |
|
266 * < 2 bytes > preSharedKey length |
|
267 * < length in bytes > preSharedKey |
|
268 * < 1 byte > pskIdentity length |
|
269 * < length in bytes > pskIdentity |
|
270 * < 1 byte > masterSecret length |
|
271 * < 1 byte > masterSecret algorithm length |
|
272 * < length in bytes > masterSecret algorithm |
|
273 * < 2 bytes > masterSecretKey length |
|
274 * < length in bytes> masterSecretKey |
|
275 * < 1 byte > useExtendedMasterSecret |
|
276 * < 1 byte > identificationProtocol length |
|
277 * < length in bytes > identificationProtocol |
|
278 * < 1 byte > serverNameIndication length |
|
279 * < length in bytes > serverNameIndication |
|
280 * < 1 byte > Number of requestedServerNames entries |
|
281 * < 1 byte > ServerName length |
|
282 * < length in bytes > ServerName |
|
283 * < 4 bytes > creationTime |
|
284 * < 1 byte > Length of peer host |
|
285 * < length in bytes > peer host |
|
286 * < 2 bytes> peer port |
|
287 * < 1 byte > Number of peerCerts entries |
|
288 * < 4 byte > peerCert length |
|
289 * < length in bytes > peerCert |
|
290 * < 1 byte > localCerts type (Cert, PSK, Anonymous) |
|
291 * Certificate |
|
292 * < 1 byte > Number of Certificate entries |
|
293 * < 4 byte> Certificate length |
|
294 * < length in bytes> Certificate |
|
295 * PSK |
|
296 * < 1 byte > Number of PSK entries |
|
297 * < 1 bytes > PSK algorithm length |
|
298 * < length in bytes > PSK algorithm string |
|
299 * < 4 bytes > PSK key length |
|
300 * < length in bytes> PSK key |
|
301 * < 4 bytes > PSK identity length |
|
302 * < length in bytes> PSK identity |
|
303 * Anonymous |
|
304 * < 1 byte > |
|
305 */ |
|
306 |
|
307 SSLSessionImpl(HandshakeContext hc, ByteBuffer buf) throws IOException { |
|
308 int i = 0; |
|
309 byte[] b; |
|
310 |
|
311 this.localSupportedSignAlgs = new ArrayList<>(); |
|
312 |
|
313 boundValues = null; |
|
314 |
|
315 this.protocolVersion = ProtocolVersion.valueOf(Short.toUnsignedInt(buf.getShort())); |
|
316 |
|
317 if (protocolVersion.useTLS13PlusSpec()) { |
|
318 this.sessionId = new SessionId(false, null); |
|
319 } else { |
|
320 // The CH session id may reset this if it's provided |
|
321 this.sessionId = new SessionId(true, |
|
322 hc.sslContext.getSecureRandom()); |
|
323 } |
|
324 |
|
325 this.cipherSuite = CipherSuite.valueOf(Short.toUnsignedInt(buf.getShort())); |
|
326 |
|
327 // Local Supported signature algorithms |
|
328 i = Short.toUnsignedInt(buf.getShort()); |
|
329 while (i-- > 0) { |
|
330 this.localSupportedSignAlgs.add(SignatureScheme.valueOf( |
|
331 Short.toUnsignedInt(buf.getShort()))); |
|
332 } |
|
333 |
|
334 // PSK |
|
335 i = Short.toUnsignedInt(buf.getShort()); |
|
336 if (i > 0) { |
|
337 b = new byte[i]; |
|
338 // Get algorithm string |
|
339 buf.get(b, 0, i); |
|
340 // Encoded length |
|
341 i = Short.toUnsignedInt(buf.getShort()); |
|
342 // Encoded SecretKey |
|
343 b = new byte[i]; |
|
344 buf.get(b); |
|
345 this.preSharedKey = new SecretKeySpec(b, "TlsMasterSecret"); |
|
346 } else { |
|
347 this.preSharedKey = null; |
|
348 } |
|
349 |
|
350 // PSK identity |
|
351 i = buf.get(); |
|
352 if (i > 0) { |
|
353 b = new byte[i]; |
|
354 buf.get(b); |
|
355 this.pskIdentity = b; |
|
356 } else { |
|
357 this.pskIdentity = null; |
|
358 } |
|
359 |
|
360 // Master secret length of secret key algorithm (one byte) |
|
361 i = buf.get(); |
|
362 if (i > 0) { |
|
363 b = new byte[i]; |
|
364 // Get algorithm string |
|
365 buf.get(b, 0, i); |
|
366 // Encoded length |
|
367 i = Short.toUnsignedInt(buf.getShort()); |
|
368 // Encoded SecretKey |
|
369 b = new byte[i]; |
|
370 buf.get(b); |
|
371 this.masterSecret = new SecretKeySpec(b, "TlsMasterSecret"); |
|
372 } else { |
|
373 this.masterSecret = null; |
|
374 } |
|
375 // Use extended master secret |
|
376 this.useExtendedMasterSecret = (buf.get() != 0); |
|
377 |
|
378 // Identification Protocol |
|
379 i = buf.get(); |
|
380 if (i == 0) { |
|
381 identificationProtocol = null; |
|
382 } else { |
|
383 b = new byte[i]; |
|
384 identificationProtocol = |
|
385 buf.get(b, 0, i).asCharBuffer().toString(); |
|
386 } |
|
387 |
|
388 // SNI |
|
389 i = buf.get(); // length |
|
390 if (i == 0) { |
|
391 serverNameIndication = null; |
|
392 } else { |
|
393 b = new byte[i]; |
|
394 buf.get(b, 0, b.length); |
|
395 serverNameIndication = new SNIHostName(b); |
|
396 } |
|
397 |
|
398 // List of SNIServerName |
|
399 int len = Short.toUnsignedInt(buf.getShort()); |
|
400 if (len == 0) { |
|
401 this.requestedServerNames = Collections.<SNIServerName>emptyList(); |
|
402 } else { |
|
403 requestedServerNames = new ArrayList<>(); |
|
404 while (len > 0) { |
|
405 int l = buf.get(); |
|
406 b = new byte[l]; |
|
407 buf.get(b, 0, l); |
|
408 requestedServerNames.add(new SNIHostName(new String(b))); |
|
409 len--; |
|
410 } |
|
411 } |
|
412 |
|
413 // Get creation time |
|
414 this.creationTime = buf.getLong(); |
|
415 |
|
416 // Get Peer host & port |
|
417 i = Byte.toUnsignedInt(buf.get()); |
|
418 if (i == 0) { |
|
419 this.host = new String(); |
|
420 } else { |
|
421 b = new byte[i]; |
|
422 this.host = buf.get(b).toString(); |
|
423 } |
|
424 this.port = Short.toUnsignedInt(buf.getShort()); |
|
425 |
|
426 // Peer certs |
|
427 i = buf.get(); |
|
428 if (i == 0) { |
|
429 this.peerCerts = null; |
|
430 } else { |
|
431 this.peerCerts = new X509Certificate[i]; |
|
432 int j = 0; |
|
433 while (i > j) { |
|
434 b = new byte[buf.getInt()]; |
|
435 buf.get(b); |
|
436 try { |
|
437 this.peerCerts[j] = new X509CertImpl(b); |
|
438 } catch (Exception e) { |
|
439 throw new IOException(e); |
|
440 } |
|
441 j++; |
|
442 } |
|
443 } |
|
444 |
|
445 // Get local certs of PSK |
|
446 switch (buf.get()) { |
|
447 case 0: |
|
448 break; |
|
449 case 1: |
|
450 // number of certs |
|
451 len = buf.get(); |
|
452 this.localCerts = new X509Certificate[len]; |
|
453 i = 0; |
|
454 while (len > i) { |
|
455 b = new byte[buf.getInt()]; |
|
456 buf.get(b); |
|
457 try { |
|
458 this.localCerts[i] = new X509CertImpl(b); |
|
459 } catch (Exception e) { |
|
460 throw new IOException(e); |
|
461 } |
|
462 i++; |
|
463 } |
|
464 break; |
|
465 case 2: |
|
466 // pre-shared key |
|
467 // Length of pre-shared key algorithm (one byte) |
|
468 i = buf.get(); |
|
469 b = new byte[i]; |
|
470 String alg = buf.get(b, 0, i).asCharBuffer().toString(); |
|
471 // Get length of encoding |
|
472 i = Short.toUnsignedInt(buf.getShort()); |
|
473 // Get encoding |
|
474 b = new byte[i]; |
|
475 buf.get(b); |
|
476 this.preSharedKey = new SecretKeySpec(b, alg); |
|
477 // Get identity len |
|
478 this.pskIdentity = new byte[buf.get()]; |
|
479 buf.get(pskIdentity); |
|
480 break; |
|
481 default: |
|
482 throw new SSLException("Failed local certs of session."); |
|
483 } |
|
484 |
|
485 context = (SSLSessionContextImpl) |
|
486 hc.sslContext.engineGetServerSessionContext(); |
|
487 } |
|
488 |
|
489 /** |
|
490 * Write out a SSLSessionImpl in a byte array for a stateless session ticket |
|
491 */ |
|
492 byte[] write() throws Exception { |
|
493 byte[] b; |
|
494 HandshakeOutStream hos = new HandshakeOutStream(null); |
|
495 |
|
496 hos.putInt16(protocolVersion.id); |
|
497 hos.putInt16(cipherSuite.id); |
|
498 |
|
499 // Local Supported signature algorithms |
|
500 int l = localSupportedSignAlgs.size(); |
|
501 hos.putInt16(l); |
|
502 SignatureScheme[] sig = new SignatureScheme[l]; |
|
503 localSupportedSignAlgs.toArray(sig); |
|
504 for (SignatureScheme s : sig) { |
|
505 hos.putInt16(s.id); |
|
506 } |
|
507 |
|
508 // PSK |
|
509 if (preSharedKey == null || |
|
510 preSharedKey.getAlgorithm() == null) { |
|
511 hos.putInt16(0); |
|
512 } else { |
|
513 hos.putInt16(preSharedKey.getAlgorithm().length()); |
|
514 if (preSharedKey.getAlgorithm().length() != 0) { |
|
515 hos.write(preSharedKey.getAlgorithm().getBytes()); |
|
516 } |
|
517 b = preSharedKey.getEncoded(); |
|
518 hos.putInt16(b.length); |
|
519 hos.write(b, 0, b.length); |
|
520 } |
|
521 |
|
522 // PSK Identity |
|
523 if (pskIdentity == null) { |
|
524 hos.putInt8(0); |
|
525 } else { |
|
526 hos.putInt8(pskIdentity.length); |
|
527 hos.write(pskIdentity, 0, pskIdentity.length); |
|
528 } |
|
529 |
|
530 // Master Secret |
|
531 if (getMasterSecret() == null || |
|
532 getMasterSecret().getAlgorithm() == null) { |
|
533 hos.putInt8(0); |
|
534 } else { |
|
535 hos.putInt8(getMasterSecret().getAlgorithm().length()); |
|
536 if (getMasterSecret().getAlgorithm().length() != 0) { |
|
537 hos.write(getMasterSecret().getAlgorithm().getBytes()); |
|
538 } |
|
539 b = getMasterSecret().getEncoded(); |
|
540 hos.putInt16(b.length); |
|
541 hos.write(b, 0, b.length); |
|
542 } |
|
543 |
|
544 hos.putInt8(useExtendedMasterSecret ? 1 : 0); |
|
545 |
|
546 // Identification Protocol |
|
547 if (identificationProtocol == null) { |
|
548 hos.putInt8(0); |
|
549 } else { |
|
550 hos.putInt8(identificationProtocol.length()); |
|
551 hos.write(identificationProtocol.getBytes(), 0, |
|
552 identificationProtocol.length()); |
|
553 } |
|
554 |
|
555 // SNI |
|
556 if (serverNameIndication == null) { |
|
557 hos.putInt8(0); |
|
558 } else { |
|
559 b = serverNameIndication.getEncoded(); |
|
560 hos.putInt8(b.length); |
|
561 hos.write(b, 0, b.length); |
|
562 } |
|
563 |
|
564 // List of SNIServerName |
|
565 hos.putInt16(requestedServerNames.size()); |
|
566 if (requestedServerNames.size() > 0) { |
|
567 for (SNIServerName host: requestedServerNames) { |
|
568 b = host.getEncoded(); |
|
569 hos.putInt8(b.length); |
|
570 hos.write(b, 0, b.length); |
|
571 } |
|
572 } |
|
573 |
|
574 ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES); |
|
575 hos.writeBytes(buffer.putLong(creationTime).array()); |
|
576 |
|
577 // peer Host & Port |
|
578 if (host == null || host.length() == 0) { |
|
579 hos.putInt8(0); |
|
580 } else { |
|
581 hos.putInt8(host.length()); |
|
582 hos.writeBytes(host.getBytes()); |
|
583 } |
|
584 hos.putInt16(port); |
|
585 |
|
586 // Peer cert |
|
587 if (peerCerts == null || peerCerts.length == 0) { |
|
588 hos.putInt8(0); |
|
589 } else { |
|
590 hos.putInt8(peerCerts.length); |
|
591 for (X509Certificate c : peerCerts) { |
|
592 b = c.getEncoded(); |
|
593 hos.putInt32(b.length); |
|
594 hos.writeBytes(b); |
|
595 } |
|
596 } |
|
597 |
|
598 // Client identity |
|
599 if (localCerts != null && localCerts.length > 0) { |
|
600 // certificate based |
|
601 hos.putInt8(1); |
|
602 hos.putInt8(localCerts.length); |
|
603 for (X509Certificate c : localCerts) { |
|
604 b = c.getEncoded(); |
|
605 hos.putInt32(b.length); |
|
606 hos.writeBytes(b); |
|
607 } |
|
608 } else if (preSharedKey != null) { |
|
609 // pre-shared key |
|
610 hos.putInt8(2); |
|
611 hos.putInt8(preSharedKey.getAlgorithm().length()); |
|
612 hos.write(preSharedKey.getAlgorithm().getBytes()); |
|
613 b = preSharedKey.getEncoded(); |
|
614 hos.putInt32(b.length); |
|
615 hos.writeBytes(b); |
|
616 hos.putInt32(pskIdentity.length); |
|
617 hos.writeBytes(pskIdentity); |
|
618 } else { |
|
619 // anonymous |
|
620 hos.putInt8(0); |
|
621 } |
|
622 |
|
623 return hos.toByteArray(); |
|
624 } |
|
625 |
254 void setMasterSecret(SecretKey secret) { |
626 void setMasterSecret(SecretKey secret) { |
255 masterSecret = secret; |
627 masterSecret = secret; |
256 } |
628 } |
257 |
629 |
258 void setResumptionMasterSecret(SecretKey secret) { |
630 void setResumptionMasterSecret(SecretKey secret) { |