/** * Initiates a TLS handshake in the role of client.<br/> * <br/> * In blocking mode, this will not return until the handshake is complete. * In non-blocking mode, use {@link TlsPeer#NotifyHandshakeComplete()} to * receive a callback when the handshake is complete. * * @param tlsClient The {@link TlsClient} to use for the handshake. * @throws IOException If in blocking mode and handshake was not successful. */ public virtual void Connect(TlsClient tlsClient) { if (tlsClient == null) { throw new ArgumentNullException("tlsClient"); } if (this.mTlsClient != null) { throw new InvalidOperationException("'Connect' can only be called once"); } this.mTlsClient = tlsClient; this.mSecurityParameters = new SecurityParameters(); this.mSecurityParameters.entity = ConnectionEnd.client; this.mTlsClientContext = new TlsClientContextImpl(mSecureRandom, mSecurityParameters); this.mSecurityParameters.clientRandom = CreateRandomBlock(tlsClient.ShouldUseGmtUnixTime(), mTlsClientContext.NonceRandomGenerator); this.mTlsClient.Init(mTlsClientContext); this.mRecordStream.Init(mTlsClientContext); TlsSession sessionToResume = tlsClient.GetSessionToResume(); if (sessionToResume != null && sessionToResume.IsResumable) { SessionParameters sessionParameters = sessionToResume.ExportSessionParameters(); if (sessionParameters != null) { this.mTlsSession = sessionToResume; this.mSessionParameters = sessionParameters; } } SendClientHelloMessage(); this.mConnectionState = CS_CLIENT_HELLO; BlockForHandshake(); }
public virtual DtlsTransport Connect(TlsClient client, DatagramTransport transport) { if (client == null) { throw new ArgumentNullException("client"); } if (transport == null) { throw new ArgumentNullException("transport"); } SecurityParameters securityParameters = new SecurityParameters(); securityParameters.entity = ConnectionEnd.client; ClientHandshakeState state = new ClientHandshakeState(); state.client = client; state.clientContext = new TlsClientContextImpl(mSecureRandom, securityParameters); securityParameters.clientRandom = TlsProtocol.CreateRandomBlock(client.ShouldUseGmtUnixTime(), state.clientContext.NonceRandomGenerator); client.Init(state.clientContext); DtlsRecordLayer recordLayer = new DtlsRecordLayer(transport, state.clientContext, client, ContentType.handshake); TlsSession sessionToResume = state.client.GetSessionToResume(); if (sessionToResume != null && sessionToResume.IsResumable) { SessionParameters sessionParameters = sessionToResume.ExportSessionParameters(); if (sessionParameters != null) { state.tlsSession = sessionToResume; state.sessionParameters = sessionParameters; } } try { return(ClientHandshake(state, recordLayer)); } catch (TlsFatalAlert fatalAlert) { AbortClientHandshake(state, recordLayer, fatalAlert.AlertDescription); throw fatalAlert; } catch (IOException e) { AbortClientHandshake(state, recordLayer, AlertDescription.internal_error); throw e; } catch (Exception e) { AbortClientHandshake(state, recordLayer, AlertDescription.internal_error); throw new TlsFatalAlert(AlertDescription.internal_error, e); } finally { securityParameters.Clear(); } }