Source Code Cross Referenced for ServerHandshakeImpl.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 org.apache.harmony.xnet.provider.jsse.SSLv3Constants;
024:        import org.apache.harmony.xnet.provider.jsse.SSLSessionImpl;
025:        import org.apache.harmony.xnet.provider.jsse.ProtocolVersion;
026:
027:        import java.io.IOException;
028:        import java.math.BigInteger;
029:        import java.security.AccessController;
030:        import java.security.KeyFactory;
031:        import java.security.KeyPair;
032:        import java.security.KeyPairGenerator;
033:        import java.security.NoSuchAlgorithmException;
034:        import java.security.PrivateKey;
035:        import java.security.PrivilegedExceptionAction;
036:        import java.security.PublicKey;
037:        import java.security.cert.CertificateException;
038:        import java.security.cert.X509Certificate;
039:        import java.security.interfaces.RSAPublicKey;
040:
041:        import java.util.Arrays;
042:
043:        import javax.crypto.Cipher;
044:        import javax.crypto.KeyAgreement;
045:        import javax.crypto.interfaces.DHPublicKey;
046:        import javax.crypto.spec.DHParameterSpec;
047:        import javax.crypto.spec.DHPublicKeySpec;
048:        import javax.net.ssl.X509ExtendedKeyManager;
049:        import javax.net.ssl.X509KeyManager;
050:        import javax.net.ssl.X509TrustManager;
051:
052:        /**
053:         * Server side handshake protocol implementation.
054:         * Handshake protocol operates on top of the Record Protocol.
055:         * It responsible for negotiating a session.
056:         * 
057:         * The implementation proceses inbound client handshake messages,
058:         * creates and sends respond messages. Outbound messages are supplied 
059:         * to Record Protocol. Detected errors are reported to the Alert protocol.
060:         * 
061:         * @see TLS 1.0 spec., 7.4. Handshake protocol.
062:         * (http://www.ietf.org/rfc/rfc2246.txt)
063:         *  
064:         */
065:        public class ServerHandshakeImpl extends HandshakeProtocol {
066:
067:            // private key used in key exchange
068:            private PrivateKey privKey;
069:
070:            /**
071:             * Creates Server Handshake Implementation
072:             * 
073:             * @param owner
074:             */
075:            public ServerHandshakeImpl(Object owner) {
076:                super (owner);
077:                status = NEED_UNWRAP;
078:            }
079:
080:            /**
081:             * Start session negotiation
082:             * @param session
083:             */
084:            public void start() {
085:                if (session == null) { // initial handshake
086:                    status = NEED_UNWRAP;
087:                    return; // wait client hello
088:                }
089:                if (clientHello != null && this .status != FINISHED) {
090:                    // current negotiation has not completed
091:                    return; // ignore
092:                }
093:
094:                // renegotiation
095:                sendHelloRequest();
096:                status = NEED_UNWRAP;
097:            }
098:
099:            /**
100:             * Proceses inbound handshake messages
101:             * @param bytes
102:             */
103:            public void unwrap(byte[] bytes) {
104:
105:                io_stream.append(bytes);
106:                while (io_stream.available() > 0) {
107:                    int handshakeType;
108:                    int length;
109:                    io_stream.mark();
110:                    try {
111:                        handshakeType = io_stream.read();
112:                        length = io_stream.readUint24();
113:                        if (io_stream.available() < length) {
114:                            io_stream.reset();
115:                            return;
116:                        }
117:
118:                        switch (handshakeType) {
119:                        case 1: // CLIENT_HELLO
120:                            if (clientHello != null && this .status != FINISHED) {
121:                                // Client hello has been received during handshake
122:                                unexpectedMessage();
123:                                return;
124:                            }
125:                            // if protocol planed to send Hello Request message
126:                            // - cancel this demand.
127:                            needSendHelloRequest = false;
128:                            clientHello = new ClientHello(io_stream, length);
129:                            if (nonBlocking) {
130:                                delegatedTasks
131:                                        .add(new DelegatedTask(
132:                                                new PrivilegedExceptionAction() {
133:                                                    public Object run()
134:                                                            throws Exception {
135:                                                        processClientHello();
136:                                                        return null;
137:                                                    }
138:                                                }, this , AccessController
139:                                                        .getContext()));
140:                                return;
141:                            }
142:                            processClientHello();
143:                            break;
144:
145:                        case 11: //    CLIENT CERTIFICATE
146:                            if (isResuming || certificateRequest == null
147:                                    || serverHelloDone == null
148:                                    || clientCert != null) {
149:                                unexpectedMessage();
150:                                return;
151:                            }
152:                            clientCert = new CertificateMessage(io_stream,
153:                                    length);
154:                            if (clientCert.certs.length == 0) {
155:                                if (parameters.getNeedClientAuth()) {
156:                                    fatalAlert(AlertProtocol.HANDSHAKE_FAILURE,
157:                                            "HANDSHAKE FAILURE: no client certificate received");
158:                                }
159:                            } else {
160:                                String authType = clientCert.certs[0]
161:                                        .getPublicKey().getAlgorithm();
162:                                try {
163:                                    parameters.getTrustManager()
164:                                            .checkClientTrusted(
165:                                                    clientCert.certs, authType);
166:                                } catch (CertificateException e) {
167:                                    fatalAlert(AlertProtocol.BAD_CERTIFICATE,
168:                                            "Untrusted Client Certificate ", e);
169:                                }
170:                                session.peerCertificates = clientCert.certs;
171:                            }
172:                            break;
173:
174:                        case 15: // CERTIFICATE_VERIFY
175:                            if (isResuming
176:                                    || clientKeyExchange == null
177:                                    || clientCert == null
178:                                    || clientKeyExchange.isEmpty() //client certificate
179:                                    // contains fixed DH
180:                                    // parameters
181:                                    || certificateVerify != null
182:                                    || changeCipherSpecReceived) {
183:                                unexpectedMessage();
184:                                return;
185:                            }
186:                            certificateVerify = new CertificateVerify(
187:                                    io_stream, length);
188:
189:                            DigitalSignature ds = new DigitalSignature(
190:                                    session.cipherSuite.keyExchange);
191:                            ds.init(serverCert.certs[0]);
192:                            byte[] md5_hash = null;
193:                            byte[] sha_hash = null;
194:
195:                            if (session.cipherSuite.keyExchange == CipherSuite.KeyExchange_RSA_EXPORT
196:                                    || session.cipherSuite.keyExchange == CipherSuite.KeyExchange_RSA
197:                                    || session.cipherSuite.keyExchange == CipherSuite.KeyExchange_DHE_RSA
198:                                    || session.cipherSuite.keyExchange == CipherSuite.KeyExchange_DHE_RSA_EXPORT) {
199:                                md5_hash = io_stream.getDigestMD5withoutLast();
200:                                sha_hash = io_stream.getDigestSHAwithoutLast();
201:                            } else if (session.cipherSuite.keyExchange == CipherSuite.KeyExchange_DHE_DSS
202:                                    || session.cipherSuite.keyExchange == CipherSuite.KeyExchange_DHE_DSS_EXPORT) {
203:                                sha_hash = io_stream.getDigestSHAwithoutLast();
204:                            } else if (session.cipherSuite.keyExchange == CipherSuite.KeyExchange_DH_anon
205:                                    || session.cipherSuite.keyExchange == CipherSuite.KeyExchange_DH_anon_EXPORT) {
206:                            }
207:                            ds.setMD5(md5_hash);
208:                            ds.setSHA(sha_hash);
209:                            if (!ds
210:                                    .verifySignature(certificateVerify.signedHash)) {
211:                                fatalAlert(AlertProtocol.DECRYPT_ERROR,
212:                                        "DECRYPT ERROR: CERTIFICATE_VERIFY incorrect signature");
213:                            }
214:                            break;
215:                        case 16: // CLIENT_KEY_EXCHANGE
216:                            if (isResuming
217:                                    || serverHelloDone == null
218:                                    || clientKeyExchange != null
219:                                    || (clientCert == null && parameters
220:                                            .getNeedClientAuth())) {
221:                                unexpectedMessage();
222:                                return;
223:                            }
224:                            if (session.cipherSuite.keyExchange == CipherSuite.KeyExchange_RSA
225:                                    || session.cipherSuite.keyExchange == CipherSuite.KeyExchange_RSA_EXPORT) {
226:                                clientKeyExchange = new ClientKeyExchange(
227:                                        io_stream, length,
228:                                        serverHello.server_version[1] == 1,
229:                                        true);
230:                                Cipher c = null;
231:                                try {
232:                                    c = Cipher
233:                                            .getInstance("RSA/ECB/PKCS1Padding");
234:                                    c.init(Cipher.DECRYPT_MODE, privKey);
235:                                    preMasterSecret = c
236:                                            .doFinal(clientKeyExchange.exchange_keys);
237:                                    // check preMasterSecret:
238:                                    if (preMasterSecret.length != 48
239:                                            || preMasterSecret[0] != clientHello.client_version[0]
240:                                            || preMasterSecret[1] != clientHello.client_version[1]) {
241:                                        // incorrect preMasterSecret
242:                                        // prevent an attack (see TLS 1.0 spec., 7.4.7.1.)
243:                                        preMasterSecret = new byte[48];
244:                                        parameters.getSecureRandom().nextBytes(
245:                                                preMasterSecret);
246:                                    }
247:                                } catch (Exception e) {
248:                                    fatalAlert(AlertProtocol.INTERNAL_ERROR,
249:                                            "INTERNAL ERROR", e);
250:                                }
251:                            } else { // diffie hellman key exchange
252:                                clientKeyExchange = new ClientKeyExchange(
253:                                        io_stream, length,
254:                                        serverHello.server_version[1] == 1,
255:                                        false);
256:                                if (clientKeyExchange.isEmpty()) {
257:                                    // TODO check that client cert. DH params
258:                                    // matched server cert. DH params
259:
260:                                    // client cert. contains fixed DH parameters 
261:                                    preMasterSecret = ((DHPublicKey) clientCert.certs[0]
262:                                            .getPublicKey()).getY()
263:                                            .toByteArray();
264:                                } else {
265:                                    PublicKey clientPublic;
266:                                    KeyAgreement agreement;
267:                                    try {
268:                                        KeyFactory kf = null;
269:                                        try {
270:                                            kf = KeyFactory.getInstance("DH");
271:                                        } catch (NoSuchAlgorithmException ee) {
272:                                            kf = KeyFactory
273:                                                    .getInstance("DiffieHellman");
274:                                        }
275:                                        try {
276:                                            agreement = KeyAgreement
277:                                                    .getInstance("DH");
278:                                        } catch (NoSuchAlgorithmException ee) {
279:                                            agreement = KeyAgreement
280:                                                    .getInstance("DiffieHellman");
281:                                        }
282:                                        clientPublic = kf
283:                                                .generatePublic(new DHPublicKeySpec(
284:                                                        new BigInteger(
285:                                                                1,
286:                                                                clientKeyExchange.exchange_keys),
287:                                                        serverKeyExchange.par1,
288:                                                        serverKeyExchange.par2));
289:                                        agreement.init(privKey);
290:                                        agreement.doPhase(clientPublic, true);
291:                                        preMasterSecret = agreement
292:                                                .generateSecret();
293:                                    } catch (Exception e) {
294:                                        fatalAlert(
295:                                                AlertProtocol.INTERNAL_ERROR,
296:                                                "INTERNAL ERROR", e);
297:                                        return;
298:                                    }
299:                                }
300:                            }
301:
302:                            computerMasterSecret();
303:                            break;
304:
305:                        case 20: // FINISHED
306:                            if (!isResuming && !changeCipherSpecReceived) {
307:                                unexpectedMessage();
308:                                return;
309:                            }
310:
311:                            clientFinished = new Finished(io_stream, length);
312:                            verifyFinished(clientFinished.getData());
313:                            parameters.getServerSessionContext().putSession(
314:                                    session);
315:                            if (!isResuming) {
316:                                sendChangeCipherSpec();
317:                            } else {
318:                                session.lastAccessedTime = System
319:                                        .currentTimeMillis();
320:                                status = FINISHED;
321:                            }
322:                            break;
323:                        default:
324:                            unexpectedMessage();
325:                            return;
326:                        }
327:                    } catch (IOException e) {
328:                        // io stream dosn't contain complete handshake message
329:                        io_stream.reset();
330:                        return;
331:                    }
332:                }
333:            }
334:
335:            /**
336:             * Processes SSLv2 Hello message
337:             * @ see TLS 1.0 spec., E.1. Version 2 client hello
338:             * @param bytes
339:             */
340:            public void unwrapSSLv2(byte[] bytes) {
341:                try {
342:                    io_stream.append(bytes);
343:                    io_stream.mark();
344:                    try {
345:                        clientHello = new ClientHello(io_stream);
346:                    } catch (IOException e) {
347:                        io_stream.reset();
348:                        return;
349:                    }
350:                    if (nonBlocking) {
351:                        delegatedTasks.add(new DelegatedTask(
352:                                new PrivilegedExceptionAction() {
353:                                    public Object run() throws Exception {
354:                                        processClientHello();
355:                                        return null;
356:                                    }
357:                                }, this , AccessController.getContext()));
358:                        return;
359:                    }
360:                    processClientHello();
361:                } catch (Exception e) {
362:                    fatalAlert(AlertProtocol.INTERNAL_ERROR, "INTERNAL ERROR",
363:                            e);
364:                }
365:            }
366:
367:            /**
368:             * 
369:             * Processes Client Hello message. 
370:             * Server responds to client hello message with server hello 
371:             * and (if necessary) server certificate, server key exchange,
372:             * certificate request, and server hello done messages.
373:             */
374:            void processClientHello() {
375:                CipherSuite cipher_suite;
376:
377:                // check that clientHello contains CompressionMethod.null
378:                checkCompression: {
379:                    for (int i = 0; i < clientHello.compression_methods.length; i++) {
380:                        if (clientHello.compression_methods[i] == 0) {
381:                            break checkCompression;
382:                        }
383:                    }
384:                    fatalAlert(AlertProtocol.HANDSHAKE_FAILURE,
385:                            "HANDSHAKE FAILURE. Incorrect client hello message");
386:                }
387:
388:                if (!ProtocolVersion.isSupported(clientHello.client_version)) {
389:                    fatalAlert(AlertProtocol.PROTOCOL_VERSION,
390:                            "PROTOCOL VERSION. Unsupported client version "
391:                                    + clientHello.client_version[0]
392:                                    + clientHello.client_version[1]);
393:                }
394:
395:                isResuming = false;
396:                FIND: if (clientHello.session_id.length != 0) {
397:                    // client wishes to reuse session
398:
399:                    SSLSessionImpl sessionToResume;
400:                    boolean reuseCurrent = false;
401:
402:                    // reuse current session
403:                    if (session != null
404:                            && Arrays
405:                                    .equals(session.id, clientHello.session_id)) {
406:                        if (session.isValid()) {
407:                            isResuming = true;
408:                            break FIND;
409:                        }
410:                        reuseCurrent = true;
411:                    }
412:
413:                    // find session in cash
414:                    sessionToResume = findSessionToResume(clientHello.session_id);
415:                    if (sessionToResume == null || !sessionToResume.isValid()) {
416:                        if (!parameters.getEnableSessionCreation()) {
417:                            if (reuseCurrent) {
418:                                // we can continue current session
419:                                sendWarningAlert(AlertProtocol.NO_RENEGOTIATION);
420:                                status = NOT_HANDSHAKING;
421:                                clearMessages();
422:                                return;
423:                            } else {
424:                                fatalAlert(AlertProtocol.HANDSHAKE_FAILURE,
425:                                        "SSL Session may not be created");
426:                            }
427:                        }
428:                        session = null;
429:                    } else {
430:                        session = (SSLSessionImpl) sessionToResume.clone();
431:                        isResuming = true;
432:                    }
433:                }
434:
435:                if (isResuming) {
436:                    cipher_suite = session.cipherSuite;
437:                    // clientHello.cipher_suites must include at least cipher_suite from the session
438:                    checkCipherSuite: {
439:                        for (int i = 0; i < clientHello.cipher_suites.length; i++) {
440:                            if (cipher_suite
441:                                    .equals(clientHello.cipher_suites[i])) {
442:                                break checkCipherSuite;
443:                            }
444:                        }
445:                        fatalAlert(AlertProtocol.HANDSHAKE_FAILURE,
446:                                "HANDSHAKE FAILURE. Incorrect client hello message");
447:                    }
448:                } else {
449:                    cipher_suite = selectSuite(clientHello.cipher_suites);
450:                    if (cipher_suite == null) {
451:                        fatalAlert(AlertProtocol.HANDSHAKE_FAILURE,
452:                                "HANDSHAKE FAILURE. NO COMMON SUITE");
453:                    }
454:                    if (!parameters.getEnableSessionCreation()) {
455:                        fatalAlert(AlertProtocol.HANDSHAKE_FAILURE,
456:                                "SSL Session may not be created");
457:                    }
458:                    session = new SSLSessionImpl(cipher_suite, parameters
459:                            .getSecureRandom());
460:                }
461:
462:                recordProtocol.setVersion(clientHello.client_version);
463:                session.protocol = ProtocolVersion
464:                        .getByVersion(clientHello.client_version);
465:                session.clientRandom = clientHello.random;
466:
467:                // create server hello message
468:                serverHello = new ServerHello(parameters.getSecureRandom(),
469:                        clientHello.client_version, session.getId(),
470:                        cipher_suite, (byte) 0); //CompressionMethod.null
471:                session.serverRandom = serverHello.random;
472:                send(serverHello);
473:                if (isResuming) {
474:                    sendChangeCipherSpec();
475:                    return;
476:                }
477:
478:                //    create and send server certificate message if needed
479:                if (!cipher_suite.isAnonymous()) { // need to send server certificate
480:                    X509Certificate[] certs = null;
481:                    String certType = null;
482:                    if (cipher_suite.keyExchange == CipherSuite.KeyExchange_RSA
483:                            || cipher_suite.keyExchange == CipherSuite.KeyExchange_RSA_EXPORT
484:                            || cipher_suite.keyExchange == CipherSuite.KeyExchange_DHE_RSA
485:                            || cipher_suite.keyExchange == CipherSuite.KeyExchange_DHE_RSA_EXPORT) {
486:                        certType = "RSA";
487:                    } else if (cipher_suite.keyExchange == CipherSuite.KeyExchange_DHE_DSS
488:                            || cipher_suite.keyExchange == CipherSuite.KeyExchange_DHE_DSS_EXPORT) {
489:                        certType = "DSA";
490:                    } else if (cipher_suite.keyExchange == CipherSuite.KeyExchange_DH_DSS) {
491:                        certType = "DH_DSA";
492:                    } else if (cipher_suite.keyExchange == CipherSuite.KeyExchange_DH_RSA) {
493:                        certType = "DH_RSA";
494:                    }
495:                    // obtain certificates from key manager
496:                    String alias = null;
497:                    X509KeyManager km = parameters.getKeyManager();
498:                    if (km instanceof  X509ExtendedKeyManager) {
499:                        X509ExtendedKeyManager ekm = (X509ExtendedKeyManager) km;
500:                        if (this .socketOwner != null) {
501:                            alias = ekm.chooseServerAlias(certType, null,
502:                                    this .socketOwner);
503:                        } else {
504:                            alias = ekm.chooseEngineServerAlias(certType, null,
505:                                    this .engineOwner);
506:                        }
507:                        if (alias != null) {
508:                            certs = ekm.getCertificateChain(alias);
509:                        }
510:                    } else {
511:                        alias = km.chooseServerAlias(certType, null,
512:                                this .socketOwner);
513:                        if (alias != null) {
514:                            certs = km.getCertificateChain(alias);
515:                        }
516:                    }
517:
518:                    if (certs == null) {
519:                        fatalAlert(AlertProtocol.HANDSHAKE_FAILURE,
520:                                "NO SERVER CERTIFICATE FOUND");
521:                        return;
522:                    }
523:                    session.localCertificates = certs;
524:                    serverCert = new CertificateMessage(certs);
525:                    privKey = parameters.getKeyManager().getPrivateKey(alias);
526:                    send(serverCert);
527:                }
528:
529:                // create and send server key exchange message if needed
530:                RSAPublicKey rsakey = null;
531:                DHPublicKeySpec dhkeySpec = null;
532:                byte[] hash = null;
533:                BigInteger p = null;
534:                BigInteger g = null;
535:
536:                KeyPairGenerator kpg = null;
537:
538:                try {
539:                    if (cipher_suite.keyExchange == CipherSuite.KeyExchange_RSA_EXPORT) {
540:                        PublicKey pk = serverCert.certs[0].getPublicKey();
541:                        if (getRSAKeyLength(pk) > 512) {
542:                            // key is longer than 512 bits
543:                            kpg = KeyPairGenerator.getInstance("RSA");
544:                            kpg.initialize(512);
545:                        }
546:                    } else if (cipher_suite.keyExchange == CipherSuite.KeyExchange_DHE_DSS
547:                            || cipher_suite.keyExchange == CipherSuite.KeyExchange_DHE_DSS_EXPORT
548:                            || cipher_suite.keyExchange == CipherSuite.KeyExchange_DHE_RSA
549:                            || cipher_suite.keyExchange == CipherSuite.KeyExchange_DHE_RSA_EXPORT
550:                            || cipher_suite.keyExchange == CipherSuite.KeyExchange_DH_anon
551:                            || cipher_suite.keyExchange == CipherSuite.KeyExchange_DH_anon_EXPORT) {
552:                        try {
553:                            kpg = KeyPairGenerator.getInstance("DH");
554:                        } catch (NoSuchAlgorithmException ee) {
555:                            kpg = KeyPairGenerator.getInstance("DiffieHellman");
556:                        }
557:                        p = new BigInteger(1, DHParameters.getPrime());
558:                        g = new BigInteger("2");
559:                        DHParameterSpec spec = new DHParameterSpec(p, g);
560:                        kpg.initialize(spec);
561:                    }
562:                } catch (Exception e) {
563:                    fatalAlert(AlertProtocol.INTERNAL_ERROR, "INTERNAL ERROR",
564:                            e);
565:                }
566:
567:                if (kpg != null) {
568:                    // need to send server key exchange message
569:                    DigitalSignature ds = new DigitalSignature(
570:                            cipher_suite.keyExchange);
571:                    KeyPair kp = null;
572:                    try {
573:                        kp = kpg.genKeyPair();
574:                        if (cipher_suite.keyExchange == CipherSuite.KeyExchange_RSA_EXPORT) {
575:                            rsakey = (RSAPublicKey) kp.getPublic();
576:                        } else {
577:                            DHPublicKey dhkey = (DHPublicKey) kp.getPublic();
578:                            KeyFactory kf = null;
579:                            try {
580:                                kf = KeyFactory.getInstance("DH");
581:                            } catch (NoSuchAlgorithmException e) {
582:                                kf = KeyFactory.getInstance("DiffieHellman");
583:                            }
584:                            dhkeySpec = (DHPublicKeySpec) kf.getKeySpec(dhkey,
585:                                    DHPublicKeySpec.class);
586:                        }
587:                        if (!cipher_suite.isAnonymous()) { // calculate signed_params
588:
589:                            // init by private key which correspond to
590:                            // server certificate
591:                            ds.init(privKey);
592:
593:                            // use emphemeral key for key exchange
594:                            privKey = kp.getPrivate();
595:                            ds.update(clientHello.getRandom());
596:                            ds.update(serverHello.getRandom());
597:
598:                            byte[] tmp;
599:                            byte[] tmpLength = new byte[2];
600:                            //FIXME 1_byte==0x00                    
601:                            if (cipher_suite.keyExchange == CipherSuite.KeyExchange_RSA_EXPORT) {
602:                                tmp = rsakey.getModulus().toByteArray();
603:                                tmpLength[0] = (byte) ((tmp.length & 0xFF00) >>> 8);
604:                                tmpLength[1] = (byte) (tmp.length & 0xFF);
605:                                ds.update(tmpLength);
606:                                ds.update(tmp);
607:                                tmp = rsakey.getPublicExponent().toByteArray();
608:                                tmpLength[0] = (byte) ((tmp.length & 0xFF00) >>> 8);
609:                                tmpLength[1] = (byte) (tmp.length & 0xFF);
610:                                ds.update(tmp);
611:                            } else {
612:                                tmp = dhkeySpec.getP().toByteArray();
613:                                tmpLength[0] = (byte) ((tmp.length & 0xFF00) >>> 8);
614:                                tmpLength[1] = (byte) (tmp.length & 0xFF);
615:                                ds.update(tmp);
616:                                tmp = dhkeySpec.getG().toByteArray();
617:                                tmpLength[0] = (byte) ((tmp.length & 0xFF00) >>> 8);
618:                                tmpLength[1] = (byte) (tmp.length & 0xFF);
619:                                ds.update(tmp);
620:                                tmp = dhkeySpec.getY().toByteArray();
621:                                tmpLength[0] = (byte) ((tmp.length & 0xFF00) >>> 8);
622:                                tmpLength[1] = (byte) (tmp.length & 0xFF);
623:                                ds.update(tmp);
624:                            }
625:                            hash = ds.sign();
626:                        } else {
627:                            privKey = kp.getPrivate(); // use emphemeral key for key exchange
628:                        }
629:                    } catch (Exception e) {
630:                        fatalAlert(AlertProtocol.INTERNAL_ERROR,
631:                                "INTERNAL ERROR", e);
632:                    }
633:
634:                    if (cipher_suite.keyExchange == CipherSuite.KeyExchange_RSA_EXPORT) {
635:                        serverKeyExchange = new ServerKeyExchange(rsakey
636:                                .getModulus(), rsakey.getPublicExponent(),
637:                                null, hash);
638:                    } else {
639:                        serverKeyExchange = new ServerKeyExchange(p, g,
640:                                dhkeySpec.getY(), hash);
641:                    }
642:                    send(serverKeyExchange);
643:                }
644:
645:                // CERTIFICATE_REQUEST
646:                certRequest: if (parameters.getWantClientAuth()
647:                        || parameters.getNeedClientAuth()) {
648:                    X509Certificate[] accepted;
649:                    try {
650:                        X509TrustManager tm = parameters.getTrustManager();
651:                        accepted = tm.getAcceptedIssuers();
652:                    } catch (ClassCastException e) {
653:                        // don't send certificateRequest
654:                        break certRequest;
655:                    }
656:                    byte[] requestedClientCertTypes = { 1, 2 }; // rsa sign, dsa sign
657:                    certificateRequest = new CertificateRequest(
658:                            requestedClientCertTypes, accepted);
659:                    send(certificateRequest);
660:                }
661:
662:                // SERVER_HELLO_DONE
663:                serverHelloDone = new ServerHelloDone();
664:                send(serverHelloDone);
665:                status = NEED_UNWRAP;
666:            }
667:
668:            /**
669:             * Creates and sends finished message
670:             */
671:            protected void makeFinished() {
672:                byte[] verify_data;
673:                boolean isTLS = (serverHello.server_version[1] == 1); // TLS 1.0 protocol
674:                if (isTLS) {
675:                    verify_data = new byte[12];
676:                    computerVerifyDataTLS("server finished", verify_data);
677:                } else { // SSL 3.0 protocol (http://wp.netscape.com/eng/ssl3)
678:                    verify_data = new byte[36];
679:                    computerVerifyDataSSLv3(SSLv3Constants.server, verify_data);
680:                }
681:                serverFinished = new Finished(verify_data);
682:                send(serverFinished);
683:                if (isResuming) {
684:                    if (isTLS) {
685:                        computerReferenceVerifyDataTLS("client finished");
686:                    } else {
687:                        computerReferenceVerifyDataSSLv3(SSLv3Constants.client);
688:                    }
689:                    status = NEED_UNWRAP;
690:                } else {
691:                    session.lastAccessedTime = System.currentTimeMillis();
692:                    status = FINISHED;
693:                }
694:            }
695:
696:            // find sesssion in the session hash
697:            private SSLSessionImpl findSessionToResume(byte[] session_id) {
698:                return (SSLSessionImpl) parameters.getServerSessionContext()
699:                        .getSession(session_id);
700:            }
701:
702:            // find appropriate cipher_suite in the client suites
703:            private CipherSuite selectSuite(CipherSuite[] client_suites) {
704:                for (int i = 0; i < client_suites.length; i++) {
705:                    if (!client_suites[i].supported) {
706:                        continue;
707:                    }
708:                    for (int j = 0; j < parameters.enabledCipherSuites.length; j++) {
709:                        if (client_suites[i]
710:                                .equals(parameters.enabledCipherSuites[j])) {
711:                            return client_suites[i];
712:                        }
713:                    }
714:                }
715:                return null;
716:            }
717:
718:            /**
719:             * Proceses inbound ChangeCipherSpec message
720:             */
721:            public void receiveChangeCipherSpec() {
722:                if (isResuming) {
723:                    if (serverFinished == null) {
724:                        unexpectedMessage();
725:                    } else {
726:                        changeCipherSpecReceived = true;
727:                    }
728:                } else {
729:                    if ((parameters.getNeedClientAuth() && clientCert == null)
730:                            || clientKeyExchange == null
731:                            || (clientCert != null
732:                                    && !clientKeyExchange.isEmpty() && certificateVerify == null)) {
733:                        unexpectedMessage();
734:                    } else {
735:                        changeCipherSpecReceived = true;
736:                    }
737:                    if (serverHello.server_version[1] == 1) {
738:                        computerReferenceVerifyDataTLS("client finished");
739:                    } else {
740:                        computerReferenceVerifyDataSSLv3(SSLv3Constants.client);
741:                    }
742:                }
743:            }
744:
745:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.