Source Code Cross Referenced for HandshakeProtocol.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 Boris Kuznetsov
020:         * @version $Revision$
021:         */package org.apache.harmony.xnet.provider.jsse;
022:
023:        import java.math.BigInteger;
024:        import java.security.GeneralSecurityException;
025:        import java.security.KeyFactory;
026:        import java.security.MessageDigest;
027:        import java.security.NoSuchAlgorithmException;
028:        import java.security.PublicKey;
029:        import java.security.interfaces.RSAKey;
030:        import java.security.spec.InvalidKeySpecException;
031:        import java.security.spec.RSAPublicKeySpec;
032:        import java.util.Arrays;
033:        import java.util.Vector;
034:
035:        import javax.net.ssl.SSLEngineResult;
036:        import javax.net.ssl.SSLException;
037:        import javax.net.ssl.SSLHandshakeException;
038:
039:        /**
040:         * Base class for ClientHandshakeImpl and ServerHandshakeImpl classes.
041:         * @see TLS 1.0 spec., 7.4. Handshake protocol
042:         * (http://www.ietf.org/rfc/rfc2246.txt)
043:         * 
044:         */
045:        public abstract class HandshakeProtocol {
046:
047:            /**
048:             * Handshake status NEED_UNWRAP - HandshakeProtocol needs to receive data 
049:             */
050:            public final static int NEED_UNWRAP = 1;
051:
052:            /**
053:             * Handshake status NOT_HANDSHAKING - is not currently handshaking
054:             */
055:            public final static int NOT_HANDSHAKING = 2;
056:
057:            /**
058:             * Handshake status FINISHED - HandshakeProtocol has just finished 
059:             */
060:            public final static int FINISHED = 3;
061:
062:            /**
063:             * Handshake status NEED_TASK - HandshakeProtocol needs the results of delegated task
064:             */
065:            public final static int NEED_TASK = 4;
066:
067:            /**
068:             * Current handshake status
069:             */
070:            protected int status = NOT_HANDSHAKING;
071:
072:            /**
073:             * IO stream for income/outcome handshake data
074:             */
075:            protected HandshakeIODataStream io_stream = new HandshakeIODataStream();
076:
077:            /**
078:             * SSL Record Protocol implementation.
079:             */
080:            protected SSLRecordProtocol recordProtocol;
081:
082:            /**
083:             * SSLParameters suplied by SSLSocket or SSLEngine
084:             */
085:            protected SSLParameters parameters;
086:
087:            /**
088:             * Delegated tasks for this handshake implementation
089:             */
090:            protected Vector delegatedTasks = new Vector();
091:
092:            /**
093:             * Indicates non-blocking handshake
094:             */
095:            protected boolean nonBlocking;
096:
097:            /**
098:             * Pending session
099:             */
100:            protected SSLSessionImpl session;
101:
102:            /**
103:             * Sended and received handshake messages
104:             */
105:            protected ClientHello clientHello;
106:            protected ServerHello serverHello;
107:            protected CertificateMessage serverCert;
108:            protected ServerKeyExchange serverKeyExchange;
109:            protected CertificateRequest certificateRequest;
110:            protected ServerHelloDone serverHelloDone;
111:            protected CertificateMessage clientCert;
112:            protected ClientKeyExchange clientKeyExchange;
113:            protected CertificateVerify certificateVerify;
114:            protected Finished clientFinished;
115:            protected Finished serverFinished;
116:
117:            /**
118:             * Indicates that change cipher spec message has been received
119:             */
120:            protected boolean changeCipherSpecReceived = false;
121:
122:            /**
123:             * Indicates previous session resuming
124:             */
125:            protected boolean isResuming = false;
126:
127:            /**
128:             *  Premaster secret
129:             */
130:            protected byte[] preMasterSecret;
131:
132:            /**
133:             * Exception occured in delegated task
134:             */
135:            protected Exception delegatedTaskErr;
136:
137:            // reference verify_data used to verify finished message
138:            private byte[] verify_data = new byte[12];
139:
140:            // Encoding of "master secret" string: "master secret".getBytes()
141:            private byte[] master_secret_bytes = { 109, 97, 115, 116, 101, 114,
142:                    32, 115, 101, 99, 114, 101, 116 };
143:
144:            // indicates whether protocol needs to send change cipher spec message
145:            private boolean needSendCCSpec = false;
146:
147:            // indicates whether protocol needs to send change cipher spec message
148:            protected boolean needSendHelloRequest = false;
149:
150:            /**
151:             * SSLEngine owning this HandshakeProtocol
152:             */
153:            public SSLEngineImpl engineOwner;
154:
155:            /**
156:             * SSLSocket owning this HandshakeProtocol
157:             */
158:            public SSLSocketImpl socketOwner;
159:
160:            /**
161:             * Creates HandshakeProtocol instance
162:             * @param owner
163:             */
164:            protected HandshakeProtocol(Object owner) {
165:                if (owner instanceof  SSLEngineImpl) {
166:                    engineOwner = (SSLEngineImpl) owner;
167:                    nonBlocking = true;
168:                    this .parameters = (SSLParameters) engineOwner.sslParameters;
169:                } else if (owner instanceof  SSLSocketImpl) {
170:                    socketOwner = (SSLSocketImpl) owner;
171:                    nonBlocking = false;
172:                    this .parameters = (SSLParameters) socketOwner.sslParameters;
173:                }
174:            }
175:
176:            /**
177:             * Sets SSL Record Protocol
178:             * @param recordProtocol
179:             */
180:            public void setRecordProtocol(SSLRecordProtocol recordProtocol) {
181:                this .recordProtocol = recordProtocol;
182:            }
183:
184:            /**
185:             * Start session negotiation
186:             * @param session
187:             */
188:            public abstract void start();
189:
190:            /**
191:             * Stops the current session renegotiation process. 
192:             * Such functionality is needed when it is session renegotiation 
193:             * process and no_renegotiation alert message is received
194:             * from another peer.
195:             * @param session
196:             */
197:            protected void stop() {
198:                clearMessages();
199:                status = NOT_HANDSHAKING;
200:            }
201:
202:            /**
203:             * Returns handshake status
204:             * @return
205:             */
206:            public SSLEngineResult.HandshakeStatus getStatus() {
207:                if (io_stream.hasData() || needSendCCSpec
208:                        || needSendHelloRequest || delegatedTaskErr != null) {
209:                    return SSLEngineResult.HandshakeStatus.NEED_WRAP;
210:                }
211:                if (!delegatedTasks.isEmpty()) {
212:                    return SSLEngineResult.HandshakeStatus.NEED_TASK;
213:                }
214:
215:                switch (status) {
216:                case HandshakeProtocol.NEED_UNWRAP:
217:                    return SSLEngineResult.HandshakeStatus.NEED_UNWRAP;
218:                case HandshakeProtocol.FINISHED:
219:                    status = NOT_HANDSHAKING;
220:                    clearMessages();
221:                    return SSLEngineResult.HandshakeStatus.FINISHED;
222:                default: // HandshakeProtocol.NOT_HANDSHAKING:
223:                    return SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING;
224:                }
225:            }
226:
227:            /**
228:             * Returns pending session
229:             * @return session
230:             */
231:            public SSLSessionImpl getSession() {
232:                return session;
233:            }
234:
235:            protected void sendChangeCipherSpec() {
236:                needSendCCSpec = true;
237:            }
238:
239:            protected void sendHelloRequest() {
240:                needSendHelloRequest = true;
241:            }
242:
243:            /**
244:             * Proceses inbound ChangeCipherSpec message
245:             */
246:            abstract void receiveChangeCipherSpec();
247:
248:            /**
249:             * Creates and sends finished message
250:             */
251:            abstract void makeFinished();
252:
253:            /**
254:             * Proceses inbound handshake messages
255:             * @param bytes
256:             */
257:            public abstract void unwrap(byte[] bytes);
258:
259:            /**
260:             * Processes SSLv2 Hello message
261:             * @param bytes
262:             */
263:            public abstract void unwrapSSLv2(byte[] bytes);
264:
265:            /**
266:             * Proceses outbound handshake messages
267:             * @return
268:             */
269:            public byte[] wrap() {
270:                if (delegatedTaskErr != null) {
271:                    // process error occured in delegated task
272:                    Exception e = delegatedTaskErr;
273:                    delegatedTaskErr = null;
274:                    fatalAlert(
275:                            AlertProtocol.HANDSHAKE_FAILURE,
276:                            "Error occured in delegated task:" + e.getMessage(),
277:                            e);
278:                }
279:                if (io_stream.hasData()) {
280:                    return recordProtocol
281:                            .wrap(ContentType.HANDSHAKE, io_stream);
282:                } else if (needSendCCSpec) {
283:                    makeFinished();
284:                    needSendCCSpec = false;
285:                    return recordProtocol
286:                            .getChangeCipherSpecMesage(getSession());
287:                } else if (needSendHelloRequest) {
288:                    needSendHelloRequest = false;
289:                    return recordProtocol.wrap(ContentType.HANDSHAKE,
290:                    // hello request message 
291:                            // (see TLS v 1 specification: 
292:                            // http://www.ietf.org/rfc/rfc2246.txt)
293:                            new byte[] { 0, 0, 0, 0 }, 0, 4);
294:                } else {
295:                    return null; // nothing to send;
296:                }
297:            }
298:
299:            /**
300:             * Sends fatal alert, breaks execution
301:             * 
302:             * @param description
303:             */
304:            protected void sendWarningAlert(byte description) {
305:                recordProtocol.alert(AlertProtocol.WARNING, description);
306:            }
307:
308:            /**
309:             * Sends fatal alert, breaks execution
310:             * 
311:             * @param description
312:             * @param reason
313:             */
314:            protected void fatalAlert(byte description, String reason) {
315:                throw new AlertException(description,
316:                        new SSLHandshakeException(reason));
317:            }
318:
319:            /**
320:             * Sends fatal alert, breaks execution
321:             * 
322:             * @param description
323:             * @param reason
324:             * @param cause
325:             */
326:            protected void fatalAlert(byte description, String reason,
327:                    Exception cause) {
328:                throw new AlertException(description, new SSLException(reason,
329:                        cause));
330:            }
331:
332:            /**
333:             * Sends fatal alert, breaks execution
334:             * 
335:             * @param description
336:             * @param cause
337:             */
338:            protected void fatalAlert(byte description, SSLException cause) {
339:                throw new AlertException(description, cause);
340:            }
341:
342:            /**
343:             * Computers reference TLS verify_data that is used to verify finished message
344:             * @see TLS spec. 7.4.9. Finished
345:             * @param label
346:             */
347:            protected void computerReferenceVerifyDataTLS(String label) {
348:                computerVerifyDataTLS(label, verify_data);
349:            }
350:
351:            /**
352:             * Computer TLS verify_data
353:             * @see TLS spec. 7.4.9. Finished
354:             * @param label
355:             * @param buf
356:             */
357:            protected void computerVerifyDataTLS(String label, byte[] buf) {
358:                byte[] md5_digest = io_stream.getDigestMD5();
359:                byte[] sha_digest = io_stream.getDigestSHA();
360:
361:                byte[] digest = new byte[md5_digest.length + sha_digest.length];
362:                System.arraycopy(md5_digest, 0, digest, 0, md5_digest.length);
363:                System.arraycopy(sha_digest, 0, digest, md5_digest.length,
364:                        sha_digest.length);
365:                try {
366:                    PRF.computePRF(buf, session.master_secret,
367:                            label.getBytes(), digest);
368:                } catch (GeneralSecurityException e) {
369:                    fatalAlert(AlertProtocol.INTERNAL_ERROR, "PRF error", e);
370:                }
371:            }
372:
373:            /**
374:             * Computer reference SSLv3 verify_data that is used to verify finished message
375:             * @see SSLv3 spec. 7.6.9. Finished
376:             * @param label
377:             */
378:            protected void computerReferenceVerifyDataSSLv3(byte[] sender) {
379:                verify_data = new byte[36];
380:                computerVerifyDataSSLv3(sender, verify_data);
381:            }
382:
383:            /**
384:             * Computer SSLv3 verify_data
385:             * @see SSLv3 spec. 7.6.9. Finished
386:             * @param label
387:             * @param buf
388:             */
389:            protected void computerVerifyDataSSLv3(byte[] sender, byte[] buf) {
390:                MessageDigest md5;
391:                MessageDigest sha;
392:                try {
393:                    md5 = MessageDigest.getInstance("MD5");
394:                    sha = MessageDigest.getInstance("SHA-1");
395:                } catch (Exception e) {
396:                    fatalAlert(AlertProtocol.INTERNAL_ERROR,
397:                            "Could not initialize the Digest Algorithms.", e);
398:                    return;
399:                }
400:                try {
401:                    byte[] hanshake_messages = io_stream.getMessages();
402:                    md5.update(hanshake_messages);
403:                    md5.update(sender);
404:                    md5.update(session.master_secret);
405:                    byte[] b = md5.digest(SSLv3Constants.MD5pad1);
406:                    md5.update(session.master_secret);
407:                    md5.update(SSLv3Constants.MD5pad2);
408:                    System.arraycopy(md5.digest(b), 0, buf, 0, 16);
409:
410:                    sha.update(hanshake_messages);
411:                    sha.update(sender);
412:                    sha.update(session.master_secret);
413:                    b = sha.digest(SSLv3Constants.SHApad1);
414:                    sha.update(session.master_secret);
415:                    sha.update(SSLv3Constants.SHApad2);
416:                    System.arraycopy(sha.digest(b), 0, buf, 16, 20);
417:                } catch (Exception e) {
418:                    fatalAlert(AlertProtocol.INTERNAL_ERROR, "INTERNAL ERROR",
419:                            e);
420:
421:                }
422:            }
423:
424:            /**
425:             * Verifies finished data
426:             * 
427:             * @param data
428:             * @param isServer
429:             */
430:            protected void verifyFinished(byte[] data) {
431:                if (!Arrays.equals(verify_data, data)) {
432:                    fatalAlert(AlertProtocol.HANDSHAKE_FAILURE,
433:                            "Incorrect FINISED");
434:                }
435:            }
436:
437:            /**
438:             * Sends fatal alert "UNEXPECTED MESSAGE"
439:             *  
440:             */
441:            protected void unexpectedMessage() {
442:                fatalAlert(AlertProtocol.UNEXPECTED_MESSAGE,
443:                        "UNEXPECTED MESSAGE");
444:            }
445:
446:            /**
447:             * Writes message to HandshakeIODataStream
448:             * 
449:             * @param message
450:             */
451:            public void send(Message message) {
452:                io_stream.writeUint8(message.getType());
453:                io_stream.writeUint24(message.length());
454:                message.send(io_stream);
455:            }
456:
457:            /**
458:             * Computers master secret
459:             *  
460:             */
461:            public void computerMasterSecret() {
462:                byte[] seed = new byte[64];
463:                System.arraycopy(clientHello.getRandom(), 0, seed, 0, 32);
464:                System.arraycopy(serverHello.getRandom(), 0, seed, 32, 32);
465:                session.master_secret = new byte[48];
466:                if (serverHello.server_version[1] == 1) { // TLSv1
467:                    try {
468:                        PRF.computePRF(session.master_secret, preMasterSecret,
469:                                master_secret_bytes, seed);
470:                    } catch (GeneralSecurityException e) {
471:                        fatalAlert(AlertProtocol.INTERNAL_ERROR, "PRF error", e);
472:                    }
473:                } else { // SSL3.0
474:                    PRF.computePRF_SSLv3(session.master_secret,
475:                            preMasterSecret, seed);
476:                }
477:
478:                //delete preMasterSecret from memory
479:                Arrays.fill(preMasterSecret, (byte) 0);
480:                preMasterSecret = null;
481:            }
482:
483:            /**
484:             * Returns a delegated task.
485:             * @return Delegated task or null
486:             */
487:            public Runnable getTask() {
488:                if (delegatedTasks.isEmpty()) {
489:                    return null;
490:                } else {
491:                    Runnable task = (Runnable) delegatedTasks.firstElement();
492:                    delegatedTasks.remove(0);
493:                    return task;
494:                }
495:            }
496:
497:            /**
498:             * 
499:             * Clears previously sended and received handshake messages
500:             */
501:            protected void clearMessages() {
502:                io_stream.clearBuffer();
503:                clientHello = null;
504:                serverHello = null;
505:                serverCert = null;
506:                serverKeyExchange = null;
507:                certificateRequest = null;
508:                serverHelloDone = null;
509:                clientCert = null;
510:                clientKeyExchange = null;
511:                certificateVerify = null;
512:                clientFinished = null;
513:                serverFinished = null;
514:            }
515:
516:            /**
517:             * Returns RSA key length
518:             * @param pk
519:             * @return
520:             * @throws NoSuchAlgorithmException
521:             * @throws InvalidKeySpecException
522:             */
523:            protected static int getRSAKeyLength(PublicKey pk)
524:                    throws NoSuchAlgorithmException, InvalidKeySpecException {
525:
526:                BigInteger mod;
527:                if (pk instanceof  RSAKey) {
528:                    mod = ((RSAKey) pk).getModulus();
529:                } else {
530:                    KeyFactory kf = KeyFactory.getInstance("RSA");
531:                    mod = ((RSAPublicKeySpec) kf.getKeySpec(pk,
532:                            RSAPublicKeySpec.class)).getModulus();
533:                }
534:                return mod.bitLength();
535:            }
536:
537:            /**
538:             * Shutdownes the protocol. It will be impossiblke to use the instance
539:             * after the calling of this method.
540:             */
541:            protected void shutdown() {
542:                clearMessages();
543:                session = null;
544:                preMasterSecret = null;
545:                delegatedTasks.clear();
546:            }
547:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.