Search in sources :

Example 16 with HandshakeCompletedEvent

use of javax.net.ssl.HandshakeCompletedEvent in project robovm by robovm.

the class SSLSocketImpl method doHandshake.

/*
     * Performs handshake process over this connection. The handshake
     * process is directed by the handshake status code provided by
     * handshake protocol. If this status is NEED_WRAP, method retrieves
     * handshake message from handshake protocol and sends it to another peer.
     * If this status is NEED_UNWRAP, method receives and processes handshake
     * message from another peer. Each of this stages (wrap/unwrap) change
     * the state of handshake protocol and this process is performed
     * until handshake status is FINISHED. After handshake process is finished
     * handshake completed event are sent to the registered listeners.
     * For more information about the handshake process see
     * TLS v1 specification (http://www.ietf.org/rfc/rfc2246.txt) p 7.3.
     */
private void doHandshake() throws IOException {
    SSLEngineResult.HandshakeStatus status;
    int type;
    try {
        while (!(status = handshakeProtocol.getStatus()).equals(SSLEngineResult.HandshakeStatus.FINISHED)) {
            if (logger != null) {
                String s = (status.equals(SSLEngineResult.HandshakeStatus.NEED_WRAP)) ? "NEED_WRAP" : (status.equals(SSLEngineResult.HandshakeStatus.NEED_UNWRAP)) ? "NEED_UNWRAP" : "STATUS: OTHER!";
                logger.println("SSLSocketImpl: HS status: " + s + " " + status);
            }
            if (status.equals(SSLEngineResult.HandshakeStatus.NEED_WRAP)) {
                output.write(handshakeProtocol.wrap());
            } else if (status.equals(SSLEngineResult.HandshakeStatus.NEED_UNWRAP)) {
                // and retrieve the type of unwrapped data
                switch(type = recordProtocol.unwrap()) {
                    case ContentType.HANDSHAKE:
                    case ContentType.CHANGE_CIPHER_SPEC:
                        break;
                    case ContentType.APPLICATION_DATA:
                        // constraints (do not expect buffer overflow).
                        break;
                    case ContentType.ALERT:
                        processAlert();
                        if (socket_was_closed) {
                            return;
                        }
                        break;
                    default:
                        // will throw exception
                        reportFatalAlert(AlertProtocol.UNEXPECTED_MESSAGE, new SSLException("Unexpected message of type " + type + " has been got"));
                }
            } else {
                // will throw exception
                reportFatalAlert(AlertProtocol.INTERNAL_ERROR, new SSLException("Handshake passed unexpected status: " + status));
            }
            if (alertProtocol.hasAlert()) {
                // warning alert occurred during wrap or unwrap
                // (note: fatal alert causes AlertException
                // to be thrown)
                output.write(alertProtocol.wrap());
                alertProtocol.setProcessed();
            }
        }
    } catch (EndOfSourceException e) {
        appDataIS.setEnd();
        throw new IOException("Connection was closed");
    } catch (AlertException e) {
        // will throw exception
        reportFatalAlert(e.getDescriptionCode(), e.getReason());
    }
    session = recordProtocol.getSession();
    if (listeners != null) {
        // notify the listeners
        HandshakeCompletedEvent event = new HandshakeCompletedEvent(this, session);
        int size = listeners.size();
        for (int i = 0; i < size; i++) {
            listeners.get(i).handshakeCompleted(event);
        }
    }
}
Also used : SSLEngineResult(javax.net.ssl.SSLEngineResult) HandshakeCompletedEvent(javax.net.ssl.HandshakeCompletedEvent) IOException(java.io.IOException) SSLException(javax.net.ssl.SSLException)

Example 17 with HandshakeCompletedEvent

use of javax.net.ssl.HandshakeCompletedEvent in project kdeconnect-android by KDE.

the class LanLinkProvider method identityPackageReceived.

private void identityPackageReceived(final NetworkPackage identityPackage, final Socket socket, final LanLink.ConnectionStarted connectionStarted) {
    String myId = DeviceHelper.getDeviceId(context);
    final String deviceId = identityPackage.getString("deviceId");
    if (deviceId.equals(myId)) {
        Log.e("KDE/LanLinkProvider", "Somehow I'm connected to myself, ignoring. This should not happen.");
        return;
    }
    // If I'm the TCP server I will be the SSL client and viceversa.
    final boolean clientMode = (connectionStarted == LanLink.ConnectionStarted.Locally);
    // Add ssl handler if device uses new protocol
    try {
        if (identityPackage.getInt("protocolVersion") >= MIN_VERSION_WITH_SSL_SUPPORT) {
            SharedPreferences preferences = context.getSharedPreferences("trusted_devices", Context.MODE_PRIVATE);
            boolean isDeviceTrusted = preferences.getBoolean(deviceId, false);
            if (isDeviceTrusted && !SslHelper.isCertificateStored(context, deviceId)) {
                //Device paired with and old version, we can't use it as we lack the certificate
                BackgroundService.RunCommand(context, new BackgroundService.InstanceCallback() {

                    @Override
                    public void onServiceStart(BackgroundService service) {
                        Device device = service.getDevice(deviceId);
                        if (device == null)
                            return;
                        device.unpair();
                        //Retry as unpaired
                        identityPackageReceived(identityPackage, socket, connectionStarted);
                    }
                });
            }
            Log.i("KDE/LanLinkProvider", "Starting SSL handshake with " + identityPackage.getString("deviceName") + " trusted:" + isDeviceTrusted);
            final SSLSocket sslsocket = SslHelper.convertToSslSocket(context, socket, deviceId, isDeviceTrusted, clientMode);
            sslsocket.addHandshakeCompletedListener(new HandshakeCompletedListener() {

                @Override
                public void handshakeCompleted(HandshakeCompletedEvent event) {
                    String mode = clientMode ? "client" : "server";
                    try {
                        Certificate certificate = event.getPeerCertificates()[0];
                        identityPackage.set("certificate", Base64.encodeToString(certificate.getEncoded(), 0));
                        Log.i("KDE/LanLinkProvider", "Handshake as " + mode + " successful with " + identityPackage.getString("deviceName") + " secured with " + event.getCipherSuite());
                        addLink(identityPackage, sslsocket, connectionStarted);
                    } catch (Exception e) {
                        Log.e("KDE/LanLinkProvider", "Handshake as " + mode + " failed with " + identityPackage.getString("deviceName"));
                        e.printStackTrace();
                        BackgroundService.RunCommand(context, new BackgroundService.InstanceCallback() {

                            @Override
                            public void onServiceStart(BackgroundService service) {
                                Device device = service.getDevice(deviceId);
                                if (device == null)
                                    return;
                                device.unpair();
                            }
                        });
                    }
                }
            });
            //Handshake is blocking, so do it on another thread and free this thread to keep receiving new connection
            new Thread(new Runnable() {

                @Override
                public void run() {
                    try {
                        sslsocket.startHandshake();
                    } catch (Exception e) {
                        Log.e("KDE/LanLinkProvider", "Handshake failed with " + identityPackage.getString("deviceName"));
                        e.printStackTrace();
                    //String[] ciphers = sslsocket.getSupportedCipherSuites();
                    //for (String cipher : ciphers) {
                    //    Log.i("SupportedCiphers","cipher: " + cipher);
                    //}
                    }
                }
            }).start();
        } else {
            addLink(identityPackage, socket, connectionStarted);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}
Also used : BackgroundService(org.kde.kdeconnect.BackgroundService) SharedPreferences(android.content.SharedPreferences) Device(org.kde.kdeconnect.Device) SSLSocket(javax.net.ssl.SSLSocket) SocketException(java.net.SocketException) IOException(java.io.IOException) HandshakeCompletedListener(javax.net.ssl.HandshakeCompletedListener) HandshakeCompletedEvent(javax.net.ssl.HandshakeCompletedEvent) Certificate(java.security.cert.Certificate)

Aggregations

HandshakeCompletedEvent (javax.net.ssl.HandshakeCompletedEvent)17 SSLSocket (javax.net.ssl.SSLSocket)14 org.apache.harmony.xnet.tests.support.mySSLSession (org.apache.harmony.xnet.tests.support.mySSLSession)8 IOException (java.io.IOException)7 HandshakeCompletedListener (javax.net.ssl.HandshakeCompletedListener)6 SSLPeerUnverifiedException (javax.net.ssl.SSLPeerUnverifiedException)5 SocketException (java.net.SocketException)4 SSLException (javax.net.ssl.SSLException)4 CertificateException (java.security.cert.CertificateException)3 SocketTimeoutException (java.net.SocketTimeoutException)2 Certificate (java.security.cert.Certificate)2 ExecutorService (java.util.concurrent.ExecutorService)2 SSLEngineResult (javax.net.ssl.SSLEngineResult)2 SSLHandshakeException (javax.net.ssl.SSLHandshakeException)2 SSLProtocolException (javax.net.ssl.SSLProtocolException)2 SSLServerSocket (javax.net.ssl.SSLServerSocket)2 SSLSession (javax.net.ssl.SSLSession)2 X509Certificate (javax.security.cert.X509Certificate)2 SharedPreferences (android.content.SharedPreferences)1 ByteArrayInputStream (java.io.ByteArrayInputStream)1