1:
37:
38:
39: package ;
40:
41: import ;
42: import ;
43:
44: import ;
45: import ;
46: import ;
47:
48: import ;
49: import ;
50: import ;
51:
52: import ;
53: import ;
54: import ;
55: import ;
56:
57: import ;
58: import ;
59: import ;
60: import ;
61: import ;
62: import ;
63: import ;
64: import ;
65:
66: public final class SSLEngineImpl extends SSLEngine
67: {
68: final SSLContextImpl contextImpl;
69: private SSLRecordHandler[] handlers;
70: private static final SystemLogger logger = SystemLogger.SYSTEM;
71: private SessionImpl session;
72: private InputSecurityParameters insec;
73: private OutputSecurityParameters outsec;
74: private boolean inClosed;
75: private boolean outClosed;
76: private boolean createSessions;
77: private boolean needClientAuth;
78: private boolean wantClientAuth;
79: private boolean initialHandshakeDone;
80: private AbstractHandshake handshake;
81: private Alert lastAlert;
82: private SSLEngineResult.HandshakeStatus handshakeStatus;
83: private boolean changeCipherSpec;
84:
85: private String[] enabledSuites;
86: private String[] enabledProtocols;
87:
88:
98: private final ByteBuffer alertBuffer;
99:
100: private Mode mode;
101:
102: private enum Mode { SERVER, CLIENT }
103:
104: SSLEngineImpl (SSLContextImpl contextImpl, String host, int port)
105: {
106: super(host, port);
107: this.contextImpl = contextImpl;
108: handlers = new SSLRecordHandler[256];
109: session = new SessionImpl();
110: session.suite = CipherSuite.TLS_NULL_WITH_NULL_NULL;
111: session.version = ProtocolVersion.TLS_1_1;
112: byte[] sid = new byte[32];
113: contextImpl.random.nextBytes(sid);
114: session.setId(new Session.ID(sid));
115: session.setRandom(contextImpl.random);
116:
117: if (Debug.DEBUG)
118: logger.logv(Component.SSL_RECORD_LAYER, "generated session ID {0} with random {1}",
119: session.id(), contextImpl.random);
120:
121:
122: insec = new InputSecurityParameters (null, null, null, session,
123: CipherSuite.TLS_NULL_WITH_NULL_NULL);
124: outsec = new OutputSecurityParameters (null, null, null, session,
125: CipherSuite.TLS_NULL_WITH_NULL_NULL);
126: inClosed = false;
127: outClosed = false;
128: needClientAuth = false;
129: wantClientAuth = false;
130: createSessions = true;
131: initialHandshakeDone = false;
132: alertBuffer = ByteBuffer.wrap (new byte[2]);
133: mode = null;
134: lastAlert = null;
135: handshakeStatus = SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING;
136: changeCipherSpec = false;
137:
138:
139: enabledProtocols = new String[] {
140: ProtocolVersion.TLS_1_1.toString(),
141: ProtocolVersion.TLS_1.toString(),
142: ProtocolVersion.SSL_3.toString()
143: };
144: enabledSuites = defaultSuites();
145: }
146:
147: static String[] defaultSuites()
148: {
149: return new String[] {
150: CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA.toString(),
151: CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA.toString(),
152: CipherSuite.TLS_DH_DSS_WITH_AES_256_CBC_SHA.toString(),
153: CipherSuite.TLS_DH_RSA_WITH_AES_256_CBC_SHA.toString(),
154: CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA.toString(),
155: CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA.toString(),
156: CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA.toString(),
157: CipherSuite.TLS_DH_DSS_WITH_AES_128_CBC_SHA.toString(),
158: CipherSuite.TLS_DH_RSA_WITH_AES_128_CBC_SHA.toString(),
159: CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA.toString(),
160: CipherSuite.TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA.toString(),
161: CipherSuite.TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA.toString(),
162: CipherSuite.TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA.toString(),
163: CipherSuite.TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA.toString(),
164: CipherSuite.TLS_RSA_WITH_3DES_EDE_CBC_SHA.toString(),
165: CipherSuite.TLS_RSA_WITH_RC4_128_MD5.toString(),
166: CipherSuite.TLS_RSA_WITH_RC4_128_SHA.toString(),
167: CipherSuite.TLS_DHE_DSS_WITH_DES_CBC_SHA.toString(),
168: CipherSuite.TLS_DHE_RSA_WITH_DES_CBC_SHA.toString(),
169: CipherSuite.TLS_DH_DSS_WITH_DES_CBC_SHA.toString(),
170: CipherSuite.TLS_DH_RSA_WITH_DES_CBC_SHA.toString(),
171: CipherSuite.TLS_RSA_WITH_DES_CBC_SHA.toString(),
172: CipherSuite.TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA.toString(),
173: CipherSuite.TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA.toString(),
174: CipherSuite.TLS_RSA_EXPORT_WITH_DES40_CBC_SHA.toString(),
175: CipherSuite.TLS_RSA_EXPORT_WITH_RC4_40_MD5.toString(),
176: CipherSuite.TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA.toString(),
177: CipherSuite.TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA.toString(),
178: CipherSuite.TLS_RSA_WITH_NULL_MD5.toString(),
179: CipherSuite.TLS_RSA_WITH_NULL_SHA.toString()
180: };
181: }
182:
183:
184:
198:
199: @Override
200: public void beginHandshake () throws SSLException
201: {
202: if (Debug.DEBUG)
203: logger.log(Component.SSL_HANDSHAKE, "{0} handshake begins", mode);
204:
205: if (mode == null)
206: throw new IllegalStateException("setUseClientMode was never used");
207:
208: switch (mode)
209: {
210: case SERVER:
211: if (getHandshakeStatus() != SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING)
212: throw new SSLException("handshake already in progress");
213: try
214: {
215: handshake = new ServerHandshake(initialHandshakeDone, this);
216: }
217: catch (NoSuchAlgorithmException nsae)
218: {
219: throw new SSLException(nsae);
220: }
221: break;
222:
223: case CLIENT:
224: try
225: {
226: handshake = new ClientHandshake(this);
227: }
228: catch (NoSuchAlgorithmException nsae)
229: {
230: throw new SSLException(nsae);
231: }
232: break;
233: }
234: }
235:
236: @Override
237: public void closeInbound()
238: {
239: inClosed = true;
240: }
241:
242: @Override
243: public void closeOutbound()
244: {
245: lastAlert = new Alert(Alert.Level.WARNING, Alert.Description.CLOSE_NOTIFY);
246: }
247:
248: @Override
249: public Runnable getDelegatedTask()
250: {
251: if (handshake == null)
252: return null;
253: return handshake.getTask();
254: }
255:
256: @Override
257: public String[] getEnabledCipherSuites()
258: {
259: return (String[]) enabledSuites.clone();
260: }
261:
262: @Override
263: public String[] getEnabledProtocols()
264: {
265: return (String[]) enabledProtocols.clone();
266: }
267:
268: @Override
269: public boolean getEnableSessionCreation()
270: {
271: return createSessions;
272: }
273:
274: @Override
275: public HandshakeStatus getHandshakeStatus()
276: {
277: if (handshake == null)
278: return HandshakeStatus.NOT_HANDSHAKING;
279: return handshake.status();
280: }
281:
282: @Override
283: public boolean getNeedClientAuth()
284: {
285: return needClientAuth;
286: }
287:
288: @Override
289: public SSLSession getSession()
290: {
291: return session;
292: }
293:
294: @Override
295: public boolean getUseClientMode ()
296: {
297: return (mode == Mode.CLIENT);
298: }
299:
300: @Override
301: public boolean getWantClientAuth()
302: {
303: return wantClientAuth;
304: }
305:
306: @Override
307: public boolean isInboundDone()
308: {
309: return inClosed;
310: }
311:
312: @Override
313: public boolean isOutboundDone()
314: {
315: return outClosed;
316: }
317:
318: @Override
319: public void setEnableSessionCreation(final boolean createSessions)
320: {
321: this.createSessions = createSessions;
322: }
323:
324: @Override
325: public void setEnabledCipherSuites(final String[] suites)
326: {
327: if (suites.length == 0)
328: throw new IllegalArgumentException("need at least one suite");
329: enabledSuites = (String[]) suites.clone();
330: }
331:
332: @Override
333: public void setEnabledProtocols(final String[] protocols)
334: {
335: if (protocols.length == 0)
336: throw new IllegalArgumentException("need at least one protocol");
337: enabledProtocols = (String[]) protocols.clone();
338: }
339:
340: @Override
341: public String[] getSupportedCipherSuites()
342: {
343:
344:
345:
346: return CipherSuite.availableSuiteNames().toArray(new String[0]);
347: }
348:
349: @Override
350: public String[] getSupportedProtocols()
351: {
352: return new String[] { ProtocolVersion.SSL_3.toString(),
353: ProtocolVersion.TLS_1.toString(),
354: ProtocolVersion.TLS_1_1.toString() };
355: }
356:
357: @Override
358: public void setNeedClientAuth(final boolean needClientAuth)
359: {
360: this.needClientAuth = needClientAuth;
361: }
362:
363: @Override
364: public void setUseClientMode (final boolean clientMode)
365: {
366: if (clientMode)
367: mode = Mode.CLIENT;
368: else
369: mode = Mode.SERVER;
370: }
371:
372: public @Override void setWantClientAuth(final boolean wantClientAuth)
373: {
374: this.wantClientAuth = wantClientAuth;
375: }
376:
377: public @Override SSLEngineResult unwrap (final ByteBuffer source,
378: final ByteBuffer[] sinks,
379: final int offset, final int length)
380: throws SSLException
381: {
382: if (mode == null)
383: throw new IllegalStateException ("setUseClientMode was never called");
384:
385: if (inClosed)
386: return new SSLEngineResult(SSLEngineResult.Status.CLOSED,
387: handshakeStatus, 0, 0);
388:
389: if (source.remaining() < 5)
390: {
391: return new SSLEngineResult(SSLEngineResult.Status.BUFFER_UNDERFLOW,
392: handshakeStatus, 0, 0);
393: }
394:
395: Record record = null;
396: boolean helloV2 = false;
397:
398:
399:
400:
401: if (!getUseClientMode() && (source.get(source.position()) & 0x80) == 0x80)
402: {
403: if (handshake == null)
404: beginHandshake();
405: int hellolen = source.getShort(source.position()) & 0x7FFF;
406: this.handshake.handleV2Hello(source.slice());
407: if (!insec.cipherSuite().equals (CipherSuite.TLS_NULL_WITH_NULL_NULL))
408: throw new SSLException ("received SSLv2 client hello in encrypted "
409: + "session; this is invalid.");
410: if (Debug.DEBUG)
411: logger.log (Component.SSL_RECORD_LAYER,
412: "converting SSLv2 client hello to version 3 hello");
413:
414: source.getShort();
415: ClientHelloV2 v2 = new ClientHelloV2(source.slice());
416:
417: if (Debug.DEBUG)
418: logger.log(Component.SSL_RECORD_LAYER, "v2 hello: {0}", v2);
419:
420: List<CipherSuite> suites = v2.cipherSpecs();
421:
422: ClientHelloBuilder hello = new ClientHelloBuilder();
423: hello.setVersion(v2.version ());
424:
425: Random random = hello.random();
426: byte[] challenge = v2.challenge();
427: if (challenge.length < 32)
428: {
429: byte[] b = new byte[32];
430: System.arraycopy(challenge, 0, b, b.length - challenge.length,
431: challenge.length);
432: challenge = b;
433: }
434: random.setGmtUnixTime((challenge[0] & 0xFF) << 24
435: | (challenge[1] & 0xFF) << 16
436: | (challenge[2] & 0xFF) << 8
437: | (challenge[3] & 0xFF));
438: random.setRandomBytes(challenge, 4);
439:
440: byte[] sessionId = v2.sessionId();
441: hello.setSessionId(sessionId, 0, sessionId.length);
442: hello.setCipherSuites(suites);
443: ArrayList<CompressionMethod> comps = new ArrayList<CompressionMethod>(1);
444: comps.add(CompressionMethod.NULL);
445: hello.setCompressionMethods(comps);
446:
447: record = new Record(ByteBuffer.allocate(hello.length() + 9));
448: record.setContentType(ContentType.HANDSHAKE);
449: record.setVersion(v2.version());
450: record.setLength(hello.length() + 4);
451:
452: Handshake handshake = new Handshake(record.fragment());
453: handshake.setLength(hello.length());
454: handshake.setType(Handshake.Type.CLIENT_HELLO);
455:
456: handshake.bodyBuffer().put(hello.buffer());
457: source.position(source.position() + hellolen);
458: helloV2 = true;
459: }
460: else
461: record = new Record(source);
462:
463: ContentType type = record.contentType ();
464:
465: if (Debug.DEBUG)
466: logger.log(Component.SSL_RECORD_LAYER, "input record:\n{0}", record);
467:
468: if (record.length() > session.getPacketBufferSize() - 5)
469: {
470: lastAlert = new Alert(Alert.Level.FATAL,
471: Alert.Description.RECORD_OVERFLOW);
472: throw new AlertException(lastAlert);
473: }
474:
475: ByteBufferOutputStream sysMsg = null;
476: ByteBuffer msg = null;
477:
478: int produced = 0;
479: try
480: {
481:
482:
483: if (record.contentType() == ContentType.APPLICATION_DATA)
484: produced = insec.decrypt(record, sinks, offset, length);
485: else
486: {
487: if (insec.cipherSuite() == CipherSuite.TLS_NULL_WITH_NULL_NULL)
488: msg = record.fragment();
489: else
490: {
491: sysMsg = new ByteBufferOutputStream();
492: insec.decrypt(record, sysMsg);
493: }
494: }
495:
496:
497: if (!helloV2)
498: source.position(source.position() + record.length() + 5);
499: }
500: catch (BufferOverflowException boe)
501: {
502:
503:
504: logger.log(Component.SSL_RECORD_LAYER, "buffer overflow when decrypting", boe);
505: return new SSLEngineResult(SSLEngineResult.Status.BUFFER_OVERFLOW,
506: handshakeStatus, 0, 0);
507: }
508: catch (IllegalBlockSizeException ibse)
509: {
510: lastAlert = new Alert(Alert.Level.FATAL,
511: Alert.Description.BAD_RECORD_MAC);
512: throw new AlertException(lastAlert, ibse);
513: }
514: catch (DataFormatException dfe)
515: {
516: lastAlert = new Alert(Alert.Level.FATAL,
517: Alert.Description.DECOMPRESSION_FAILURE);
518: throw new AlertException(lastAlert, dfe);
519: }
520: catch (MacException me)
521: {
522: lastAlert = new Alert(Alert.Level.FATAL,
523: Alert.Description.BAD_RECORD_MAC);
524: throw new AlertException(lastAlert, me);
525: }
526: catch (ShortBufferException sbe)
527: {
528:
529: lastAlert = new Alert(Alert.Level.FATAL,
530: Alert.Description.INTERNAL_ERROR);
531: throw new AlertException(lastAlert, sbe);
532: }
533:
534: SSLEngineResult result = null;
535:
536:
537:
538: if (sysMsg != null)
539: {
540: if (Debug.DEBUG)
541: logger.logv(Component.SSL_RECORD_LAYER, "sysmessage {0}", sysMsg);
542: msg = sysMsg.buffer();
543: }
544:
545: if (type == ContentType.CHANGE_CIPHER_SPEC)
546: {
547:
548:
549: if (msg.remaining() == 0)
550: {
551: result = new SSLEngineResult (SSLEngineResult.Status.OK,
552: handshakeStatus,
553: record.length() + 5, 0);
554: }
555: else
556: {
557: byte b = msg.get();
558: if (b != 1)
559: throw new SSLException ("unknown ChangeCipherSpec value: " + (b & 0xFF));
560: InputSecurityParameters params = handshake.getInputParams();
561: logger.log (Component.SSL_RECORD_LAYER,
562: "switching to input security parameters {0}",
563: params.cipherSuite());
564: insec = params;
565: result = new SSLEngineResult (SSLEngineResult.Status.OK,
566: handshakeStatus,
567: record.length() + 5, 0);
568: }
569: }
570: else if (type == ContentType.ALERT)
571: {
572: int len = 0;
573: if (alertBuffer.position() > 0)
574: {
575: alertBuffer.put(msg.get());
576: len = 1;
577: }
578: if (Debug.DEBUG)
579: logger.logv(Component.SSL_RECORD_LAYER, "processing alerts {0}",
580: Util.wrapBuffer(msg));
581: len += msg.remaining() / 2;
582: Alert[] alerts = new Alert[len];
583: int i = 0;
584: if (alertBuffer.position() > 0)
585: {
586: alertBuffer.flip();
587: alerts[0] = new Alert(alertBuffer);
588: i++;
589: }
590: while (i < alerts.length)
591: {
592: alerts[i++] = new Alert(msg.duplicate());
593: msg.position(msg.position() + 2);
594: }
595: if (Debug.DEBUG)
596: logger.logv(Component.SSL_RECORD_LAYER, "alerts: {0}", alerts.length);
597:
598: for (i = 0; i < alerts.length; i++)
599: {
600: if (alerts[i].level() == Alert.Level.FATAL)
601: throw new AlertException(alerts[i], false);
602: if (alerts[i].description() != Alert.Description.CLOSE_NOTIFY)
603: logger.log(java.util.logging.Level.WARNING,
604: "received alert: {0}", alerts[i]);
605: if (alerts[i].description() == Alert.Description.CLOSE_NOTIFY)
606: inClosed = true;
607: }
608:
609: if (msg.hasRemaining())
610: alertBuffer.position(0).limit(2);
611:
612: result = new SSLEngineResult (SSLEngineResult.Status.OK,
613: handshakeStatus,
614: record.length() + 5, 0);
615: }
616: else if (type == ContentType.HANDSHAKE)
617: {
618: if (handshake == null)
619: beginHandshake();
620: try
621: {
622: handshakeStatus = handshake.handleInput(msg);
623: }
624: catch (AlertException ae)
625: {
626: lastAlert = ae.alert();
627: return new SSLEngineResult(SSLEngineResult.Status.OK,
628: SSLEngineResult.HandshakeStatus.NEED_WRAP,
629: 0, 0);
630: }
631: if (Debug.DEBUG)
632: logger.logv(Component.SSL_HANDSHAKE, "handshake status {0}", handshakeStatus);
633: result = new SSLEngineResult(SSLEngineResult.Status.OK,
634: handshakeStatus,
635: record.length() + 5,
636: 0);
637: if (handshakeStatus == HandshakeStatus.FINISHED)
638: {
639: handshake = null;
640: handshakeStatus = HandshakeStatus.NOT_HANDSHAKING;
641: }
642: }
643: else if (type == ContentType.APPLICATION_DATA)
644: {
645:
646:
647: result = new SSLEngineResult(SSLEngineResult.Status.OK,
648: handshakeStatus,
649: record.length() + 5,
650: produced);
651: }
652: else
653: {
654: SSLRecordHandler handler = handlers[type.getValue()];
655: if (handler != null)
656: {
657: result = new SSLEngineResult(SSLEngineResult.Status.OK,
658: handshakeStatus,
659: record.length() + 5,
660: 0);
661: }
662: else
663: throw new SSLException ("unknown content type: " + type);
664: }
665:
666: if (Debug.DEBUG)
667: logger.logv(Component.SSL_RECORD_LAYER, "return result: {0}", result);
668:
669: return result;
670: }
671:
672: public @Override SSLEngineResult wrap (ByteBuffer[] sources, int offset, int length,
673: ByteBuffer sink)
674: throws SSLException
675: {
676: if (mode == null)
677: throw new IllegalStateException ("setUseClientMode was never called");
678:
679: if (outClosed)
680: return new SSLEngineResult(SSLEngineResult.Status.CLOSED,
681: handshakeStatus, 0, 0);
682:
683: ContentType type = null;
684: ByteBuffer sysMessage = null;
685: if (Debug.DEBUG)
686: logger.logv(Component.SSL_RECORD_LAYER, "wrap {0} {1} {2} {3} / {4}",
687: sources, offset, length, sink, getHandshakeStatus());
688: if (lastAlert != null)
689: {
690: type = ContentType.ALERT;
691: sysMessage = ByteBuffer.allocate(2);
692: Alert alert = new Alert(sysMessage);
693: alert.setDescription(lastAlert.description());
694: alert.setLevel(lastAlert.level());
695: if (lastAlert.description() == Alert.Description.CLOSE_NOTIFY)
696: outClosed = true;
697: }
698: else if (changeCipherSpec)
699: {
700: type = ContentType.CHANGE_CIPHER_SPEC;
701: sysMessage = ByteBuffer.allocate(1);
702: sysMessage.put(0, (byte) 1);
703: }
704: else if (getHandshakeStatus() == SSLEngineResult.HandshakeStatus.NEED_WRAP)
705: {
706:
707:
708: if (outsec.suite() == CipherSuite.TLS_NULL_WITH_NULL_NULL)
709: {
710: int orig = sink.position();
711: sink.order(ByteOrder.BIG_ENDIAN);
712: sink.put((byte) ContentType.HANDSHAKE.getValue());
713: sink.putShort((short) session.version.rawValue());
714: sink.putShort((short) 0);
715: handshakeStatus = handshake.handleOutput(sink);
716: int produced = sink.position() - orig;
717: sink.putShort(orig + 3, (short) (produced - 5));
718: if (Debug.DEBUG)
719: logger.logv(Component.SSL_RECORD_LAYER, "emitting record:\n{0}",
720: new Record((ByteBuffer) sink.duplicate().position(orig)));
721: SSLEngineResult result = new SSLEngineResult(SSLEngineResult.Status.OK,
722: handshakeStatus, 0, produced);
723:
724:
725:
726:
727: if (handshakeStatus == HandshakeStatus.FINISHED)
728: {
729: handshake = null;
730: handshakeStatus = HandshakeStatus.NOT_HANDSHAKING;
731: }
732: return result;
733: }
734:
735:
736: sysMessage = ByteBuffer.allocate(sink.remaining() - 2048);
737: type = ContentType.HANDSHAKE;
738: try
739: {
740: handshakeStatus = handshake.handleOutput(sysMessage);
741: }
742: catch (AlertException ae)
743: {
744: lastAlert = ae.alert();
745: return new SSLEngineResult(Status.OK,
746: HandshakeStatus.NEED_WRAP, 0, 0);
747: }
748: sysMessage.flip();
749: if (Debug.DEBUG)
750: logger.logv(Component.SSL_HANDSHAKE, "handshake status {0}",
751: handshakeStatus);
752: }
753:
754: int produced = 0;
755: int consumed = 0;
756:
757: try
758: {
759: int orig = sink.position();
760: int[] inout = null;
761: if (sysMessage != null)
762: {
763: if (Debug.DEBUG)
764: logger.logv(Component.SSL_RECORD_LAYER, "encrypt system message {0} to {1}", sysMessage, sink);
765: inout = outsec.encrypt(new ByteBuffer[] { sysMessage }, 0, 1,
766: type, sink);
767: produced = inout[1];
768: }
769: else
770: {
771: if (outsec.needToSplitPayload())
772: {
773: inout = outsec.encrypt(sources, offset, 1,
774: ContentType.APPLICATION_DATA, sink);
775: consumed = inout[0];
776: produced = inout[1];
777: if (length > 1)
778: {
779: inout = outsec.encrypt(sources, offset+1, length-1,
780: ContentType.APPLICATION_DATA, sink);
781: consumed += inout[0];
782: produced += inout[1];
783: }
784: }
785: else
786: {
787: inout = outsec.encrypt(sources, offset, length,
788: ContentType.APPLICATION_DATA, sink);
789: consumed = inout[0];
790: produced = inout[1];
791: }
792: }
793:
794: if (Debug.DEBUG)
795: logger.logv(Component.SSL_RECORD_LAYER, "emitting record:\n{0}",
796: new Record((ByteBuffer) sink.duplicate().position(orig).limit(produced)));
797: }
798: catch (ShortBufferException sbe)
799: {
800:
801:
802: lastAlert = new Alert(Alert.Level.FATAL, Alert.Description.INTERNAL_ERROR);
803: return new SSLEngineResult(SSLEngineResult.Status.OK, handshakeStatus, 0, 0);
804: }
805: catch (IllegalBlockSizeException ibse)
806: {
807:
808:
809: lastAlert = new Alert(Alert.Level.FATAL, Alert.Description.INTERNAL_ERROR);
810: return new SSLEngineResult(SSLEngineResult.Status.OK, handshakeStatus, 0, 0);
811: }
812: catch (DataFormatException dfe)
813: {
814:
815: lastAlert = new Alert(Alert.Level.FATAL, Alert.Description.INTERNAL_ERROR);
816: return new SSLEngineResult(SSLEngineResult.Status.OK, handshakeStatus, 0, 0);
817: }
818:
819: if (lastAlert != null && lastAlert.level() == Alert.Level.FATAL)
820: {
821: AlertException ae = new AlertException(lastAlert);
822: lastAlert = null;
823: throw ae;
824: }
825:
826: if (changeCipherSpec)
827: {
828: outsec = handshake.getOutputParams();
829: changeCipherSpec = false;
830: }
831: SSLEngineResult result
832: = new SSLEngineResult(outClosed ? SSLEngineResult.Status.CLOSED
833: : SSLEngineResult.Status.OK,
834: handshakeStatus, consumed, produced);
835: if (handshakeStatus == HandshakeStatus.FINISHED)
836: {
837: handshake = null;
838: handshakeStatus = HandshakeStatus.NOT_HANDSHAKING;
839: }
840: return result;
841: }
842:
843:
844:
845: SessionImpl session ()
846: {
847: return session;
848: }
849:
850: void setSession(SessionImpl session)
851: {
852: this.session = session;
853: }
854:
855: void changeCipherSpec()
856: {
857: changeCipherSpec = true;
858: }
859: }