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);
}
}
}
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();
}
}
Aggregations