Source Code Cross Referenced for SSLEngineImpl.java in  » Apache-Harmony-Java-SE » org-package » org » apache » harmony » xnet » provider » jsse » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Apache Harmony Java SE » org package » org.apache.harmony.xnet.provider.jsse 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         *  Licensed to the Apache Software Foundation (ASF) under one or more
003:         *  contributor license agreements.  See the NOTICE file distributed with
004:         *  this work for additional information regarding copyright ownership.
005:         *  The ASF licenses this file to You under the Apache License, Version 2.0
006:         *  (the "License"); you may not use this file except in compliance with
007:         *  the License.  You may obtain a copy of the License at
008:         *
009:         *     http://www.apache.org/licenses/LICENSE-2.0
010:         *
011:         *  Unless required by applicable law or agreed to in writing, software
012:         *  distributed under the License is distributed on an "AS IS" BASIS,
013:         *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014:         *  See the License for the specific language governing permissions and
015:         *  limitations under the License.
016:         */
017:
018:        /**
019:         * @author Alexander Y. Kleymenov
020:         * @version $Revision$
021:         */package org.apache.harmony.xnet.provider.jsse;
022:
023:        import org.apache.harmony.xnet.provider.jsse.AlertException;
024:        import org.apache.harmony.xnet.provider.jsse.SSLSessionImpl;
025:        import org.apache.harmony.xnet.provider.jsse.SSLEngineDataStream;
026:
027:        import java.io.IOException;
028:        import java.nio.BufferUnderflowException;
029:        import java.nio.ByteBuffer;
030:        import java.nio.ReadOnlyBufferException;
031:        import javax.net.ssl.SSLEngine;
032:        import javax.net.ssl.SSLHandshakeException;
033:        import javax.net.ssl.SSLEngineResult;
034:        import javax.net.ssl.SSLException;
035:        import javax.net.ssl.SSLSession;
036:
037:        /**
038:         * Implementation of SSLEngine.
039:         * @see javax.net.ssl.SSLEngine class documentation for more information.
040:         */
041:        public class SSLEngineImpl extends SSLEngine {
042:
043:            // indicates if peer mode was set
044:            private boolean peer_mode_was_set = false;
045:            // indicates if handshake has been started
046:            private boolean handshake_started = false;
047:            // indicates if inbound operations finished
048:            private boolean isInboundDone = false;
049:            // indicates if outbound operations finished
050:            private boolean isOutboundDone = false;
051:            // indicates if close_notify alert had been sent to another peer
052:            private boolean close_notify_was_sent = false;
053:            // indicates if close_notify alert had been received from another peer
054:            private boolean close_notify_was_received = false;
055:            // indicates if engine was closed (it means that
056:            // all the works on it are done, except (probably) some finalizing work)
057:            private boolean engine_was_closed = false;
058:            // indicates if engine was shutted down (it means that
059:            // all cleaning work had been done and the engine is not operable)
060:            private boolean engine_was_shutteddown = false;
061:
062:            // record protocol to be used
063:            protected SSLRecordProtocol recordProtocol;
064:            // input stream for record protocol
065:            private SSLBufferedInput recProtIS;
066:            // handshake protocol to be used
067:            private HandshakeProtocol handshakeProtocol;
068:            // alert protocol to be used
069:            private AlertProtocol alertProtocol;
070:            // place where application data will be stored
071:            private SSLEngineAppData appData;
072:            // outcoming application data stream
073:            private SSLEngineDataStream dataStream = new SSLEngineDataStream();
074:            // active session object
075:            private SSLSessionImpl session;
076:
077:            // peer configuration parameters
078:            protected SSLParameters sslParameters;
079:
080:            // in case of emergency situations when data could not be
081:            // placed in destination buffers it will be stored in this
082:            // fields
083:            private byte[] remaining_wrapped_data = null;
084:            private byte[] remaining_hsh_data = null;
085:
086:            // logger
087:            private Logger.Stream logger = Logger.getStream("engine");
088:
089:            /**
090:             * Ctor
091:             * @param   sslParameters:  SSLParameters
092:             */
093:            protected SSLEngineImpl(SSLParameters sslParameters) {
094:                super ();
095:                this .sslParameters = sslParameters;
096:            }
097:
098:            /**
099:             * Ctor
100:             * @param   host:   String
101:             * @param   port:   int
102:             * @param   sslParameters:  SSLParameters
103:             */
104:            protected SSLEngineImpl(String host, int port,
105:                    SSLParameters sslParameters) {
106:                super (host, port);
107:                this .sslParameters = sslParameters;
108:            }
109:
110:            /**
111:             * Starts the handshake.
112:             * @throws  SSLException
113:             * @see javax.net.ssl.SSLEngine#beginHandshake() method documentation
114:             * for more information
115:             */
116:            public void beginHandshake() throws SSLException {
117:                if (engine_was_closed) {
118:                    throw new SSLException("Engine has already been closed.");
119:                }
120:                if (!peer_mode_was_set) {
121:                    throw new IllegalStateException(
122:                            "Client/Server mode was not set");
123:                }
124:                if (!handshake_started) {
125:                    handshake_started = true;
126:                    if (getUseClientMode()) {
127:                        handshakeProtocol = new ClientHandshakeImpl(this );
128:                    } else {
129:                        handshakeProtocol = new ServerHandshakeImpl(this );
130:                    }
131:                    appData = new SSLEngineAppData();
132:                    alertProtocol = new AlertProtocol();
133:                    recProtIS = new SSLBufferedInput();
134:                    recordProtocol = new SSLRecordProtocol(handshakeProtocol,
135:                            alertProtocol, recProtIS, appData);
136:                }
137:                handshakeProtocol.start();
138:            }
139:
140:            /**
141:             * Closes inbound operations of this engine
142:             * @throws  SSLException
143:             * @see javax.net.ssl.SSLEngine#closeInbound() method documentation
144:             * for more information
145:             */
146:            public void closeInbound() throws SSLException {
147:                if (logger != null) {
148:                    logger.println("closeInbound() " + isInboundDone);
149:                }
150:                if (isInboundDone) {
151:                    return;
152:                }
153:                isInboundDone = true;
154:                engine_was_closed = true;
155:                if (handshake_started) {
156:                    if (!close_notify_was_received) {
157:                        if (session != null) {
158:                            session.invalidate();
159:                        }
160:                        alertProtocol.alert(AlertProtocol.FATAL,
161:                                AlertProtocol.INTERNAL_ERROR);
162:                        throw new SSLException(
163:                                "Inbound is closed before close_notify "
164:                                        + "alert has been received.");
165:                    }
166:                } else {
167:                    // engine is closing before initial handshake has been made
168:                    shutdown();
169:                }
170:            }
171:
172:            /**
173:             * Closes outbound operations of this engine
174:             * @see javax.net.ssl.SSLEngine#closeOutbound() method documentation
175:             * for more information
176:             */
177:            public void closeOutbound() {
178:                if (logger != null) {
179:                    logger.println("closeOutbound() " + isOutboundDone);
180:                }
181:                if (isOutboundDone) {
182:                    return;
183:                }
184:                isOutboundDone = true;
185:                if (handshake_started) {
186:                    // initial handshake had been started
187:                    alertProtocol.alert(AlertProtocol.WARNING,
188:                            AlertProtocol.CLOSE_NOTIFY);
189:                    close_notify_was_sent = true;
190:                } else {
191:                    // engine is closing before initial handshake has been made
192:                    shutdown();
193:                }
194:                engine_was_closed = true;
195:            }
196:
197:            /**
198:             * Returns handshake's delegated tasks to be run
199:             * @return the delegated task to be executed.
200:             * @see javax.net.ssl.SSLEngine#getDelegatedTask() method documentation
201:             * for more information
202:             */
203:            public Runnable getDelegatedTask() {
204:                return handshakeProtocol.getTask();
205:            }
206:
207:            /**
208:             * Returns names of supported cipher suites.
209:             * @return array of strings containing the names of supported cipher suites
210:             * @see javax.net.ssl.SSLEngine#getSupportedCipherSuites() method
211:             * documentation for more information
212:             */
213:            public String[] getSupportedCipherSuites() {
214:                return CipherSuite.getSupportedCipherSuiteNames();
215:            }
216:
217:            // --------------- SSLParameters based methods ---------------------
218:
219:            /**
220:             * This method works according to the specification of implemented class.
221:             * @see javax.net.ssl.SSLEngine#getEnabledCipherSuites() method
222:             * documentation for more information
223:             */
224:            public String[] getEnabledCipherSuites() {
225:                return sslParameters.getEnabledCipherSuites();
226:            }
227:
228:            /**
229:             * This method works according to the specification of implemented class.
230:             * @see javax.net.ssl.SSLEngine#setEnabledCipherSuites(String) method
231:             * documentation for more information
232:             */
233:            public void setEnabledCipherSuites(String[] suites) {
234:                sslParameters.setEnabledCipherSuites(suites);
235:            }
236:
237:            /**
238:             * This method works according to the specification of implemented class.
239:             * @see javax.net.ssl.SSLEngine#getSupportedProtocols() method
240:             * documentation for more information
241:             */
242:            public String[] getSupportedProtocols() {
243:                return (String[]) ProtocolVersion.supportedProtocols.clone();
244:            }
245:
246:            /**
247:             * This method works according to the specification of implemented class.
248:             * @see javax.net.ssl.SSLEngine#getEnabledProtocols() method
249:             * documentation for more information
250:             */
251:            public String[] getEnabledProtocols() {
252:                return sslParameters.getEnabledProtocols();
253:            }
254:
255:            /**
256:             * This method works according to the specification of implemented class.
257:             * @see javax.net.ssl.SSLEngine#setEnabledProtocols(String) method
258:             * documentation for more information
259:             */
260:            public void setEnabledProtocols(String[] protocols) {
261:                sslParameters.setEnabledProtocols(protocols);
262:            }
263:
264:            /**
265:             * This method works according to the specification of implemented class.
266:             * @see javax.net.ssl.SSLEngine#setUseClientMode(boolean) method
267:             * documentation for more information
268:             */
269:            public void setUseClientMode(boolean mode) {
270:                if (handshake_started) {
271:                    throw new IllegalArgumentException(
272:                            "Could not change the mode after the initial handshake has begun.");
273:                }
274:                sslParameters.setUseClientMode(mode);
275:                peer_mode_was_set = true;
276:            }
277:
278:            /**
279:             * This method works according to the specification of implemented class.
280:             * @see javax.net.ssl.SSLEngine#getUseClientMode() method
281:             * documentation for more information
282:             */
283:            public boolean getUseClientMode() {
284:                return sslParameters.getUseClientMode();
285:            }
286:
287:            /**
288:             * This method works according to the specification of implemented class.
289:             * @see javax.net.ssl.SSLEngine#setNeedClientAuth(boolean) method
290:             * documentation for more information
291:             */
292:            public void setNeedClientAuth(boolean need) {
293:                sslParameters.setNeedClientAuth(need);
294:            }
295:
296:            /**
297:             * This method works according to the specification of implemented class.
298:             * @see javax.net.ssl.SSLEngine#getNeedClientAuth() method
299:             * documentation for more information
300:             */
301:            public boolean getNeedClientAuth() {
302:                return sslParameters.getNeedClientAuth();
303:            }
304:
305:            /**
306:             * This method works according to the specification of implemented class.
307:             * @see javax.net.ssl.SSLEngine#setWantClientAuth(boolean) method
308:             * documentation for more information
309:             */
310:            public void setWantClientAuth(boolean want) {
311:                sslParameters.setWantClientAuth(want);
312:            }
313:
314:            /**
315:             * This method works according to the specification of implemented class.
316:             * @see javax.net.ssl.SSLEngine#getWantClientAuth() method
317:             * documentation for more information
318:             */
319:            public boolean getWantClientAuth() {
320:                return sslParameters.getWantClientAuth();
321:            }
322:
323:            /**
324:             * This method works according to the specification of implemented class.
325:             * @see javax.net.ssl.SSLEngine#setEnableSessionCreation(boolean) method
326:             * documentation for more information
327:             */
328:            public void setEnableSessionCreation(boolean flag) {
329:                sslParameters.setEnableSessionCreation(flag);
330:            }
331:
332:            /**
333:             * This method works according to the specification of implemented class.
334:             * @see javax.net.ssl.SSLEngine#getEnableSessionCreation() method
335:             * documentation for more information
336:             */
337:            public boolean getEnableSessionCreation() {
338:                return sslParameters.getEnableSessionCreation();
339:            }
340:
341:            // -----------------------------------------------------------------
342:
343:            /**
344:             * This method works according to the specification of implemented class.
345:             * @see javax.net.ssl.SSLEngine#getHandshakeStatus() method
346:             * documentation for more information
347:             */
348:            public SSLEngineResult.HandshakeStatus getHandshakeStatus() {
349:                if (!handshake_started || engine_was_shutteddown) {
350:                    // initial handshake has not been started yet
351:                    return SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING;
352:                }
353:                if (alertProtocol.hasAlert()) {
354:                    // need to send an alert
355:                    return SSLEngineResult.HandshakeStatus.NEED_WRAP;
356:                }
357:                if (close_notify_was_sent && !close_notify_was_received) {
358:                    // waiting for "close_notify" response
359:                    return SSLEngineResult.HandshakeStatus.NEED_UNWRAP;
360:                }
361:                return handshakeProtocol.getStatus();
362:            }
363:
364:            /**
365:             * This method works according to the specification of implemented class.
366:             * @see javax.net.ssl.SSLEngine#getSession() method
367:             * documentation for more information
368:             */
369:            public SSLSession getSession() {
370:                if (session != null) {
371:                    return session;
372:                } else {
373:                    return SSLSessionImpl.NULL_SESSION;
374:                }
375:            }
376:
377:            /**
378:             * This method works according to the specification of implemented class.
379:             * @see javax.net.ssl.SSLEngine#isInboundDone() method
380:             * documentation for more information
381:             */
382:            public boolean isInboundDone() {
383:                return isInboundDone || engine_was_closed;
384:            }
385:
386:            /**
387:             * This method works according to the specification of implemented class.
388:             * @see javax.net.ssl.SSLEngine#isOutboundDone() method
389:             * documentation for more information
390:             */
391:            public boolean isOutboundDone() {
392:                return isOutboundDone;
393:            }
394:
395:            /**
396:             * Decodes one complete SSL/TLS record provided in the source buffer.
397:             * If decoded record contained application data, this data will
398:             * be placed in the destination buffers.
399:             * For more information about TLS record fragmentation see
400:             * TLS v 1 specification (http://www.ietf.org/rfc/rfc2246.txt) p 6.2.
401:             * @param src source buffer containing SSL/TLS record.
402:             * @param dsts destination buffers to place received application data.
403:             * @see javax.net.ssl.SSLEngine#unwrap(ByteBuffer,ByteBuffer[],int,int)
404:             * method documentation for more information
405:             */
406:            public SSLEngineResult unwrap(ByteBuffer src, ByteBuffer[] dsts,
407:                    int offset, int length) throws SSLException {
408:                if (engine_was_shutteddown) {
409:                    return new SSLEngineResult(SSLEngineResult.Status.CLOSED,
410:                            SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING, 0,
411:                            0);
412:                }
413:                if ((src == null) || (dsts == null)) {
414:                    throw new IllegalStateException(
415:                            "Some of the input parameters are null");
416:                }
417:
418:                if (!handshake_started) {
419:                    beginHandshake();
420:                }
421:
422:                SSLEngineResult.HandshakeStatus handshakeStatus = getHandshakeStatus();
423:                // If is is initial handshake or connection closure stage,
424:                // check if this call was made in spite of handshake status
425:                if ((session == null || engine_was_closed)
426:                        && (handshakeStatus
427:                                .equals(SSLEngineResult.HandshakeStatus.NEED_WRAP) || handshakeStatus
428:                                .equals(SSLEngineResult.HandshakeStatus.NEED_TASK))) {
429:                    return new SSLEngineResult(getEngineStatus(),
430:                            handshakeStatus, 0, 0);
431:                }
432:
433:                if (src.remaining() < recordProtocol.getMinRecordSize()) {
434:                    return new SSLEngineResult(
435:                            SSLEngineResult.Status.BUFFER_UNDERFLOW,
436:                            getHandshakeStatus(), 0, 0);
437:                }
438:
439:                try {
440:                    src.mark();
441:                    // check the destination buffers and count their capacity
442:                    int capacity = 0;
443:                    for (int i = offset; i < offset + length; i++) {
444:                        if (dsts[i] == null) {
445:                            throw new IllegalStateException(
446:                                    "Some of the input parameters are null");
447:                        }
448:                        if (dsts[i].isReadOnly()) {
449:                            throw new ReadOnlyBufferException();
450:                        }
451:                        capacity += dsts[i].remaining();
452:                    }
453:                    if (capacity < recordProtocol.getDataSize(src.remaining())) {
454:                        return new SSLEngineResult(
455:                                SSLEngineResult.Status.BUFFER_OVERFLOW,
456:                                getHandshakeStatus(), 0, 0);
457:                    }
458:                    recProtIS.setSourceBuffer(src);
459:                    // unwrap the record contained in source buffer, pass it
460:                    // to appropriate client protocol (alert, handshake, or app)
461:                    // and retrieve the type of unwrapped data
462:                    int type = recordProtocol.unwrap();
463:                    // process the data and return the result
464:                    switch (type) {
465:                    case ContentType.HANDSHAKE:
466:                    case ContentType.CHANGE_CIPHER_SPEC:
467:                        if (handshakeProtocol.getStatus().equals(
468:                                SSLEngineResult.HandshakeStatus.FINISHED)) {
469:                            session = recordProtocol.getSession();
470:                        }
471:                        break;
472:                    case ContentType.APPLICATION_DATA:
473:                        break;
474:                    case ContentType.ALERT:
475:                        if (alertProtocol.isFatalAlert()) {
476:                            alertProtocol.setProcessed();
477:                            if (session != null) {
478:                                session.invalidate();
479:                            }
480:                            String description = "Fatal alert received "
481:                                    + alertProtocol.getAlertDescription();
482:                            shutdown();
483:                            throw new SSLException(description);
484:                        } else {
485:                            if (logger != null) {
486:                                logger
487:                                        .println("Warning allert has been received: "
488:                                                + alertProtocol
489:                                                        .getAlertDescription());
490:                            }
491:                            switch (alertProtocol.getDescriptionCode()) {
492:                            case AlertProtocol.CLOSE_NOTIFY:
493:                                alertProtocol.setProcessed();
494:                                close_notify_was_received = true;
495:                                if (!close_notify_was_sent) {
496:                                    closeOutbound();
497:                                    closeInbound();
498:                                } else {
499:                                    closeInbound();
500:                                    shutdown();
501:                                }
502:                                break;
503:                            case AlertProtocol.NO_RENEGOTIATION:
504:                                alertProtocol.setProcessed();
505:                                if (session == null) {
506:                                    // message received during the initial 
507:                                    // handshake
508:                                    throw new AlertException(
509:                                            AlertProtocol.HANDSHAKE_FAILURE,
510:                                            new SSLHandshakeException(
511:                                                    "Received no_renegotiation "
512:                                                            + "during the initial handshake"));
513:                                } else {
514:                                    // just stop the handshake
515:                                    handshakeProtocol.stop();
516:                                }
517:                                break;
518:                            default:
519:                                alertProtocol.setProcessed();
520:                            }
521:                        }
522:                        break;
523:                    }
524:                    return new SSLEngineResult(getEngineStatus(),
525:                            getHandshakeStatus(), recProtIS.consumed(),
526:                            // place the app. data (if any) into the dest. buffers 
527:                            // and get the number of produced bytes:
528:                            appData.placeTo(dsts, offset, length));
529:                } catch (BufferUnderflowException e) {
530:                    // there was not enought data ource buffer to make complete packet
531:                    src.reset();
532:                    return new SSLEngineResult(
533:                            SSLEngineResult.Status.BUFFER_UNDERFLOW,
534:                            getHandshakeStatus(), 0, 0);
535:                } catch (AlertException e) {
536:                    // fatal alert occured
537:                    alertProtocol.alert(AlertProtocol.FATAL, e
538:                            .getDescriptionCode());
539:                    engine_was_closed = true;
540:                    src.reset();
541:                    if (session != null) {
542:                        session.invalidate();
543:                    }
544:                    // shutdown work will be made after the alert will be sent
545:                    // to another peer (by wrap method)
546:                    throw e.getReason();
547:                } catch (SSLException e) {
548:                    throw e;
549:                } catch (IOException e) {
550:                    alertProtocol.alert(AlertProtocol.FATAL,
551:                            AlertProtocol.INTERNAL_ERROR);
552:                    engine_was_closed = true;
553:                    // shutdown work will be made after the alert will be sent
554:                    // to another peer (by wrap method)
555:                    throw new SSLException(e.getMessage());
556:                }
557:            }
558:
559:            /**
560:             * Encodes the application data into SSL/TLS record. If handshake status
561:             * of the engine differs from NOT_HANDSHAKING the operation can work
562:             * without consuming of the source data.
563:             * For more information about TLS record fragmentation see
564:             * TLS v 1 specification (http://www.ietf.org/rfc/rfc2246.txt) p 6.2.
565:             * @param srcs the source buffers with application data to be encoded
566:             * into SSL/TLS record.
567:             * @param offset the offset in the destination buffers array pointing to
568:             * the first buffer with the source data.
569:             * @param len specifies the maximum number of buffers to be procesed.
570:             * @param dst the destination buffer where encoded data will be placed.
571:             * @see javax.net.ssl.SSLEngine#wrap(ByteBuffer[],int,int,ByteBuffer) method
572:             * documentation for more information
573:             */
574:            public SSLEngineResult wrap(ByteBuffer[] srcs, int offset, int len,
575:                    ByteBuffer dst) throws SSLException {
576:                if (engine_was_shutteddown) {
577:                    return new SSLEngineResult(SSLEngineResult.Status.CLOSED,
578:                            SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING, 0,
579:                            0);
580:                }
581:                if ((srcs == null) || (dst == null)) {
582:                    throw new IllegalStateException(
583:                            "Some of the input parameters are null");
584:                }
585:                if (dst.isReadOnly()) {
586:                    throw new ReadOnlyBufferException();
587:                }
588:
589:                if (!handshake_started) {
590:                    beginHandshake();
591:                }
592:
593:                SSLEngineResult.HandshakeStatus handshakeStatus = getHandshakeStatus();
594:                // If it is an initial handshake or connection closure stage,
595:                // check if this call was made in spite of handshake status
596:                if ((session == null || engine_was_closed)
597:                        && (handshakeStatus
598:                                .equals(SSLEngineResult.HandshakeStatus.NEED_UNWRAP) || handshakeStatus
599:                                .equals(SSLEngineResult.HandshakeStatus.NEED_TASK))) {
600:                    return new SSLEngineResult(getEngineStatus(),
601:                            handshakeStatus, 0, 0);
602:                }
603:
604:                int capacity = dst.remaining();
605:                int produced = 0;
606:
607:                if (alertProtocol.hasAlert()) {
608:                    // we have an alert to be sent
609:                    if (capacity < recordProtocol.getRecordSize(2)) {
610:                        return new SSLEngineResult(
611:                                SSLEngineResult.Status.BUFFER_OVERFLOW,
612:                                handshakeStatus, 0, 0);
613:                    }
614:                    byte[] alert_data = alertProtocol.wrap();
615:                    // place the alert record into destination
616:                    dst.put(alert_data);
617:                    if (alertProtocol.isFatalAlert()) {
618:                        alertProtocol.setProcessed();
619:                        if (session != null) {
620:                            session.invalidate();
621:                        }
622:                        // fatal alert has been sent, so shut down the engine
623:                        shutdown();
624:                        return new SSLEngineResult(
625:                                SSLEngineResult.Status.CLOSED,
626:                                SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING,
627:                                0, alert_data.length);
628:                    } else {
629:                        alertProtocol.setProcessed();
630:                        // check if the works on this engine have been done
631:                        if (close_notify_was_sent && close_notify_was_received) {
632:                            shutdown();
633:                            return new SSLEngineResult(
634:                                    SSLEngineResult.Status.CLOSED,
635:                                    SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING,
636:                                    0, alert_data.length);
637:                        }
638:                        return new SSLEngineResult(getEngineStatus(),
639:                                getHandshakeStatus(), 0, alert_data.length);
640:                    }
641:                }
642:
643:                if (capacity < recordProtocol.getMinRecordSize()) {
644:                    if (logger != null) {
645:                        logger.println("Capacity of the destination("
646:                                + capacity + ") < MIN_PACKET_SIZE("
647:                                + recordProtocol.getMinRecordSize() + ")");
648:                    }
649:                    return new SSLEngineResult(
650:                            SSLEngineResult.Status.BUFFER_OVERFLOW,
651:                            handshakeStatus, 0, 0);
652:                }
653:
654:                try {
655:                    if (!handshakeStatus
656:                            .equals(SSLEngineResult.HandshakeStatus.NEED_WRAP)) {
657:                        // so we wraps application data
658:                        dataStream.setSourceBuffers(srcs, offset, len);
659:                        if ((capacity < SSLRecordProtocol.MAX_SSL_PACKET_SIZE)
660:                                && (capacity < recordProtocol
661:                                        .getRecordSize(dataStream.available()))) {
662:                            if (logger != null) {
663:                                logger
664:                                        .println("The destination buffer("
665:                                                + capacity
666:                                                + ") can not take the resulting packet("
667:                                                + recordProtocol
668:                                                        .getRecordSize(dataStream
669:                                                                .available())
670:                                                + ")");
671:                            }
672:                            return new SSLEngineResult(
673:                                    SSLEngineResult.Status.BUFFER_OVERFLOW,
674:                                    handshakeStatus, 0, 0);
675:                        }
676:                        if (remaining_wrapped_data == null) {
677:                            remaining_wrapped_data = recordProtocol.wrap(
678:                                    ContentType.APPLICATION_DATA, dataStream);
679:                        }
680:                        if (capacity < remaining_wrapped_data.length) {
681:                            // It should newer happen because we checked the destination
682:                            // buffer size, but there is a possibility
683:                            // (if dest buffer was filled outside)
684:                            // so we just remember the data into remaining_wrapped_data
685:                            // and will enclose it during the the next call
686:                            return new SSLEngineResult(
687:                                    SSLEngineResult.Status.BUFFER_OVERFLOW,
688:                                    handshakeStatus, dataStream.consumed(), 0);
689:                        } else {
690:                            dst.put(remaining_wrapped_data);
691:                            produced = remaining_wrapped_data.length;
692:                            remaining_wrapped_data = null;
693:                            return new SSLEngineResult(getEngineStatus(),
694:                                    handshakeStatus, dataStream.consumed(),
695:                                    produced);
696:                        }
697:                    } else {
698:                        if (remaining_hsh_data == null) {
699:                            remaining_hsh_data = handshakeProtocol.wrap();
700:                        }
701:                        if (capacity < remaining_hsh_data.length) {
702:                            // It should newer happen because we checked the destination
703:                            // buffer size, but there is a possibility
704:                            // (if dest buffer was filled outside)
705:                            // so we just remember the data into remaining_hsh_data
706:                            // and will enclose it during the the next call
707:                            return new SSLEngineResult(
708:                                    SSLEngineResult.Status.BUFFER_OVERFLOW,
709:                                    handshakeStatus, 0, 0);
710:                        } else {
711:                            dst.put(remaining_hsh_data);
712:                            produced = remaining_hsh_data.length;
713:                            remaining_hsh_data = null;
714:
715:                            handshakeStatus = handshakeProtocol.getStatus();
716:                            if (handshakeStatus
717:                                    .equals(SSLEngineResult.HandshakeStatus.FINISHED)) {
718:                                session = recordProtocol.getSession();
719:                            }
720:                        }
721:                        return new SSLEngineResult(getEngineStatus(),
722:                                getHandshakeStatus(), 0, produced);
723:                    }
724:                } catch (AlertException e) {
725:                    // fatal alert occured
726:                    alertProtocol.alert(AlertProtocol.FATAL, e
727:                            .getDescriptionCode());
728:                    engine_was_closed = true;
729:                    if (session != null) {
730:                        session.invalidate();
731:                    }
732:                    // shutdown work will be made after the alert will be sent
733:                    // to another peer (by wrap method)
734:                    throw e.getReason();
735:                }
736:            }
737:
738:            // Shutdownes the engine and makes all cleanup work.
739:            private void shutdown() {
740:                engine_was_closed = true;
741:                engine_was_shutteddown = true;
742:                isOutboundDone = true;
743:                isInboundDone = true;
744:                if (handshake_started) {
745:                    alertProtocol.shutdown();
746:                    alertProtocol = null;
747:                    handshakeProtocol.shutdown();
748:                    handshakeProtocol = null;
749:                    recordProtocol.shutdown();
750:                    recordProtocol = null;
751:                }
752:            }
753:
754:            private SSLEngineResult.Status getEngineStatus() {
755:                return (engine_was_closed) ? SSLEngineResult.Status.CLOSED
756:                        : SSLEngineResult.Status.OK;
757:            }
758:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.