Source Code Cross Referenced for HandshakeIODataStream.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.SSLInputStream;
025:
026:        import java.io.IOException;
027:        import java.io.PrintStream;
028:        import java.security.MessageDigest;
029:        import java.util.Arrays;
030:        import javax.net.ssl.SSLHandshakeException;
031:
032:        /**
033:         * This class provides Input/Output data functionality
034:         * for handshake layer. It provides read and write operations
035:         * and accumulates all sent/received handshake's data.
036:         * This class can be presented as a combination of 2 data pipes.
037:         * The first data pipe is a pipe of income data: append method
038:         * places the data at the beginning of the pipe, and read methods
039:         * consume the data from the pipe. The second pipe is an outcoming
040:         * data pipe: write operations plases the data into the pipe,
041:         * and getData methods consume the data.
042:         * It is important to note that work with pipe cound not be
043:         * started if there is unconsumed data in another pipe. It is
044:         * reasoned by the following: handshake protocol performs read
045:         * and write operations consecuently. I.e. it first reads all
046:         * income data and only than produces the responce and places it
047:         * into the stream.
048:         * The read operations of the stream presented by the methods
049:         * of SSLInputStream which in its turn is an extension of InputStream.
050:         * So this stream can be used as an InputStream parameter for
051:         * certificate generation.
052:         * Also input stream functionality supports marks. The marks
053:         * help to reset the position of the stream in case of incompleate
054:         * handshake records. Note that in case of exhausting
055:         * of income data the EndOfBufferException is thown which implies
056:         * the following:
057:         *  1. the stream contains scrappy handshake record,
058:         *  2. the read position should be reseted to marked,
059:         *  3. and more income data is expected.
060:         * The throwing of the exception (instead of returning of -1 value
061:         * or incompleate filling of destination buffer)
062:         * helps to speed up the process of scrappy data recognition and
063:         * processing.
064:         * For more information about TLS handshake process see
065:         * TLS v 1 specification at http://www.ietf.org/rfc/rfc2246.txt.
066:         */
067:        public class HandshakeIODataStream extends SSLInputStream implements 
068:                org.apache.harmony.xnet.provider.jsse.Appendable, DataStream {
069:
070:            // Objects are used to compute digests of data passed
071:            // during the handshake phase
072:            private static final MessageDigest md5;
073:            private static final MessageDigest sha;
074:
075:            static {
076:                try {
077:                    md5 = MessageDigest.getInstance("MD5");
078:                    sha = MessageDigest.getInstance("SHA-1");
079:                } catch (Exception e) {
080:                    e.printStackTrace();
081:                    throw new RuntimeException(
082:                            "Could not initialize the Digest Algorithms.");
083:                }
084:            }
085:
086:            public HandshakeIODataStream() {
087:            }
088:
089:            // buffer is used to keep the handshaking data;
090:            private int buff_size = 1024;
091:            private int inc_buff_size = 1024;
092:            private byte[] buffer = new byte[buff_size];
093:
094:            // ---------------- Input related functionality -----------------
095:
096:            // position of the next byte to read
097:            private int read_pos;
098:            private int marked_pos;
099:            // position of the last byte to read + 1
100:            private int read_pos_end;
101:
102:            public int available() {
103:                return read_pos_end - read_pos;
104:            }
105:
106:            public boolean markSupported() {
107:                return true;
108:            }
109:
110:            public void mark(int limit) {
111:                marked_pos = read_pos;
112:            }
113:
114:            public void mark() {
115:                marked_pos = read_pos;
116:            }
117:
118:            public void reset() {
119:                read_pos = marked_pos;
120:            }
121:
122:            /**
123:             * Removes the data from the marked position to
124:             * the current read position. The method is usefull when it is needed
125:             * to delete one message from the internal buffer.
126:             */
127:            protected void removeFromMarkedPosition() {
128:                System.arraycopy(buffer, read_pos, buffer, marked_pos,
129:                        read_pos_end - read_pos);
130:                read_pos_end -= (read_pos - marked_pos);
131:                read_pos = marked_pos;
132:            }
133:
134:            /**
135:             * read an opaque value;
136:             * @param   byte:   byte
137:             * @return
138:             */
139:            public int read() throws IOException {
140:                if (read_pos == read_pos_end) {
141:                    //return -1;
142:                    throw new EndOfBufferException();
143:                }
144:                return buffer[read_pos++] & 0xFF;
145:            }
146:
147:            /**
148:             * reads vector of opaque values
149:             * @param   new:    long
150:             * @return
151:             */
152:            public byte[] read(int length) throws IOException {
153:                if (length > available()) {
154:                    throw new EndOfBufferException();
155:                }
156:                byte[] res = new byte[length];
157:                System.arraycopy(buffer, read_pos, res, 0, length);
158:                read_pos = read_pos + length;
159:                return res;
160:            }
161:
162:            public int read(byte[] dest, int offset, int length)
163:                    throws IOException {
164:                if (length > available()) {
165:                    throw new EndOfBufferException();
166:                }
167:                System.arraycopy(buffer, read_pos, dest, offset, length);
168:                read_pos = read_pos + length;
169:                return length;
170:            }
171:
172:            // ------------------- Extending of the input data ---------------------
173:
174:            /**
175:             * Appends the income data to be read by handshake protocol.
176:             * The attempts to overflow the buffer by means of this methods
177:             * seem to be futile because of:
178:             * 1. The SSL protocol specifies the maximum size of the record
179:             * and record protocol does not pass huge messages. 
180:             * (see TLS v1 specification http://www.ietf.org/rfc/rfc2246.txt ,
181:             * p 6.2)
182:             * 2. After each call of this method, handshake protocol should
183:             * start (and starts) the operations on received data and recognize
184:             * the fake data if such was provided (to check the size of certificate
185:             * for example).
186:             */
187:            public void append(byte[] src) {
188:                append(src, 0, src.length);
189:            }
190:
191:            private void append(byte[] src, int from, int length) {
192:                if (read_pos == read_pos_end) {
193:                    // start reading state after writing
194:                    if (write_pos_beg != write_pos) {
195:                        // error: outboud handshake data was not sent,
196:                        // but inbound handshake data has been received.
197:                        throw new AlertException(
198:                                AlertProtocol.UNEXPECTED_MESSAGE,
199:                                new SSLHandshakeException(
200:                                        "Handshake message has been received before "
201:                                                + "the last oubound message had been sent."));
202:                    }
203:                    if (read_pos < write_pos) {
204:                        read_pos = write_pos;
205:                        read_pos_end = read_pos;
206:                    }
207:                }
208:                if (read_pos_end + length > buff_size) {
209:                    enlargeBuffer(read_pos_end + length - buff_size);
210:                }
211:                System.arraycopy(src, from, buffer, read_pos_end, length);
212:                read_pos_end += length;
213:            }
214:
215:            private void enlargeBuffer(int size) {
216:                buff_size = (size < inc_buff_size) ? buff_size + inc_buff_size
217:                        : buff_size + size;
218:                byte[] new_buff = new byte[buff_size];
219:                System.arraycopy(buffer, 0, new_buff, 0, buffer.length);
220:                buffer = new_buff;
221:            }
222:
223:            protected void clearBuffer() {
224:                read_pos = 0;
225:                marked_pos = 0;
226:                read_pos_end = 0;
227:                write_pos = 0;
228:                write_pos_beg = 0;
229:                Arrays.fill(buffer, (byte) 0);
230:            }
231:
232:            // ------------------- Output related functionality --------------------
233:
234:            // position in the buffer available for write
235:            private int write_pos;
236:            // position in the buffer where the last write session has begun
237:            private int write_pos_beg;
238:
239:            // checks if the data can be written in the buffer
240:            private void check(int length) {
241:                // (write_pos == write_pos_beg) iff:
242:                // 1. there were not write operations yet
243:                // 2. all written data was demanded by getData methods
244:                if (write_pos == write_pos_beg) {
245:                    // just started to write after the reading
246:                    if (read_pos != read_pos_end) {
247:                        // error: attempt to write outbound data into the stream before
248:                        // all the inbound handshake data had been read
249:                        throw new AlertException(AlertProtocol.INTERNAL_ERROR,
250:                                new SSLHandshakeException(
251:                                        "Data was not fully read: " + read_pos
252:                                                + " " + read_pos_end));
253:                    }
254:                    // set up the write positions
255:                    if (write_pos_beg < read_pos_end) {
256:                        write_pos_beg = read_pos_end;
257:                        write_pos = write_pos_beg;
258:                    }
259:                }
260:                // if there is not enought free space in the buffer - enlarge it:
261:                if (write_pos + length >= buff_size) {
262:                    enlargeBuffer(length);
263:                }
264:            }
265:
266:            /**
267:             * Writes an opaque value
268:             * @param   byte:   byte
269:             */
270:            public void write(byte b) {
271:                check(1);
272:                buffer[write_pos++] = b;
273:            }
274:
275:            /**
276:             * Writes Uint8 value
277:             * @param long: the value to be written (last byte)
278:             */
279:            public void writeUint8(long n) {
280:                check(1);
281:                buffer[write_pos++] = (byte) (n & 0x00ff);
282:            }
283:
284:            /**
285:             * Writes Uint16 value
286:             * @param long: the value to be written (last 2 bytes)
287:             */
288:            public void writeUint16(long n) {
289:                check(2);
290:                buffer[write_pos++] = (byte) ((n & 0x00ff00) >> 8);
291:                buffer[write_pos++] = (byte) (n & 0x00ff);
292:            }
293:
294:            /**
295:             * Writes Uint24 value
296:             * @param long: the value to be written (last 3 bytes)
297:             */
298:            public void writeUint24(long n) {
299:                check(3);
300:                buffer[write_pos++] = (byte) ((n & 0x00ff0000) >> 16);
301:                buffer[write_pos++] = (byte) ((n & 0x00ff00) >> 8);
302:                buffer[write_pos++] = (byte) (n & 0x00ff);
303:            }
304:
305:            /**
306:             * Writes Uint32 value
307:             * @param long: the value to be written (last 4 bytes)
308:             */
309:            public void writeUint32(long n) {
310:                check(4);
311:                buffer[write_pos++] = (byte) ((n & 0x00ff000000) >> 24);
312:                buffer[write_pos++] = (byte) ((n & 0x00ff0000) >> 16);
313:                buffer[write_pos++] = (byte) ((n & 0x00ff00) >> 8);
314:                buffer[write_pos++] = (byte) (n & 0x00ff);
315:            }
316:
317:            /**
318:             * Writes Uint64 value
319:             * @param long: the value to be written
320:             */
321:            public void writeUint64(long n) {
322:                check(8);
323:                buffer[write_pos++] = (byte) ((n & 0x00ff00000000000000L) >> 56);
324:                buffer[write_pos++] = (byte) ((n & 0x00ff000000000000L) >> 48);
325:                buffer[write_pos++] = (byte) ((n & 0x00ff0000000000L) >> 40);
326:                buffer[write_pos++] = (byte) ((n & 0x00ff00000000L) >> 32);
327:                buffer[write_pos++] = (byte) ((n & 0x00ff000000) >> 24);
328:                buffer[write_pos++] = (byte) ((n & 0x00ff0000) >> 16);
329:                buffer[write_pos++] = (byte) ((n & 0x00ff00) >> 8);
330:                buffer[write_pos++] = (byte) (n & 0x00ff);
331:            }
332:
333:            /**
334:             * writes vector of opaque values
335:             * @param  vector the vector to be written
336:             */
337:            public void write(byte[] vector) {
338:                check(vector.length);
339:                System.arraycopy(vector, 0, buffer, write_pos, vector.length);
340:                write_pos += vector.length;
341:            }
342:
343:            // ------------------- Retrieve the written bytes ----------------------
344:
345:            public boolean hasData() {
346:                return (write_pos > write_pos_beg);
347:            }
348:
349:            /**
350:             * returns the chunk of stored data with the length no more than specified.
351:             * @param   length: int
352:             * @return
353:             */
354:            public byte[] getData(int length) {
355:                byte[] res;
356:                if (write_pos - write_pos_beg < length) {
357:                    res = new byte[write_pos - write_pos_beg];
358:                    System.arraycopy(buffer, write_pos_beg, res, 0, write_pos
359:                            - write_pos_beg);
360:                    write_pos_beg = write_pos;
361:                } else {
362:                    res = new byte[length];
363:                    System.arraycopy(buffer, write_pos_beg, res, 0, length);
364:                    write_pos_beg += length;
365:                }
366:                return res;
367:            }
368:
369:            // ---------------------- Debud functionality -------------------------
370:
371:            protected void printContent(PrintStream outstream) {
372:                int perLine = 20;
373:                String prefix = " ";
374:                String delimiter = "";
375:
376:                for (int i = write_pos_beg; i < write_pos; i++) {
377:                    String tail = Integer.toHexString(0x00ff & buffer[i])
378:                            .toUpperCase();
379:                    if (tail.length() == 1) {
380:                        tail = "0" + tail;
381:                    }
382:                    outstream.print(prefix + tail + delimiter);
383:
384:                    if (((i - write_pos_beg + 1) % 10) == 0) {
385:                        outstream.print(" ");
386:                    }
387:
388:                    if (((i - write_pos_beg + 1) % perLine) == 0) {
389:                        outstream.println();
390:                    }
391:                }
392:                outstream.println();
393:            }
394:
395:            // ---------------------- Message Digest Functionality ----------------
396:
397:            /**
398:             * Returns the MD5 digest of the data passed throught the stream
399:             * @return MD5 digest
400:             */
401:            protected byte[] getDigestMD5() {
402:                synchronized (md5) {
403:                    int len = (read_pos_end > write_pos) ? read_pos_end
404:                            : write_pos;
405:                    md5.update(buffer, 0, len);
406:                    return md5.digest();
407:                }
408:            }
409:
410:            /**
411:             * Returns the SHA-1 digest of the data passed throught the stream
412:             * @return SHA-1 digest
413:             */
414:            protected byte[] getDigestSHA() {
415:                synchronized (sha) {
416:                    int len = (read_pos_end > write_pos) ? read_pos_end
417:                            : write_pos;
418:                    sha.update(buffer, 0, len);
419:                    return sha.digest();
420:                }
421:            }
422:
423:            /**
424:             * Returns the MD5 digest of the data passed throught the stream
425:             * except last message
426:             * @return MD5 digest
427:             */
428:            protected byte[] getDigestMD5withoutLast() {
429:                synchronized (md5) {
430:                    md5.update(buffer, 0, marked_pos);
431:                    return md5.digest();
432:                }
433:            }
434:
435:            /**
436:             * Returns the SHA-1 digest of the data passed throught the stream
437:             * except last message
438:             * @return SHA-1 digest
439:             */
440:            protected byte[] getDigestSHAwithoutLast() {
441:                synchronized (sha) {
442:                    sha.update(buffer, 0, marked_pos);
443:                    return sha.digest();
444:                }
445:            }
446:
447:            /**
448:             * Returns all the data passed throught the stream
449:             * @return all the data passed throught the stream at the moment
450:             */
451:            protected byte[] getMessages() {
452:                int len = (read_pos_end > write_pos) ? read_pos_end : write_pos;
453:                byte[] res = new byte[len];
454:                System.arraycopy(buffer, 0, res, 0, len);
455:                return res;
456:            }
457:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.