void BuildAndSendApplicationRecords(byte [] bData) { int nLengthRemaining = bData.Length; int nAt = 0; while (nLengthRemaining > 0) { int nLengthToSend = ((bData.Length - nAt) > TLSRecord.MaxUncompressedRecordSize) ? TLSRecord.MaxUncompressedRecordSize : bData.Length - nAt; TLSApplicationMessage msg = new TLSApplicationMessage(); msg.ApplicationData = new byte[nLengthToSend]; Array.Copy(bData, nAt, msg.ApplicationData, 0, nLengthToSend); TLSRecord record = new TLSRecord(); record.ContentType = TLSContentType.Application; record.Messages.Add(msg); /// Encrypt the record if we are in that state byte[] bEncryptedGenericBlockCipher = state.CompressEncryptOutgoingData(record); byte[] bSend = record.GetBytesWithEncryptedContent(bEncryptedGenericBlockCipher); /// Leave this to the higer layer to send, though we could send it here Client.Send(bSend, bSend.Length, false); nAt += nLengthToSend; nLengthRemaining -= nLengthToSend; } }
/// <summary> /// A new TLS record has been received... It may contain multiple messages, so these need to be parsed /// </summary> /// <param name="record"></param> List <byte[]> ParseAndHandleTLSRecords(TLSRecord record) { List <byte[]> ApplicationDataReturned = new List <byte[]>(); /// Decrypt our message if we are at that stage /// try { record = state.DecompressRecord(record); } catch (Exception ex) { System.Diagnostics.Debug.WriteLine("!!! Exception decompressing record: {0}", ex); SendAlert(AlertLevel.fatal, AlertDescription.BadRecordMAC); this.Client.Disconnect(); return(ApplicationDataReturned); } /// Let the record parse it's content - couldn't do that until now that it's decrypted record.Content = record.RawSetContent; if (SocketClient.ShowDebug == true) { record.DebugDump(true); } foreach (TLSMessage tlsmsg in record.Messages) { if (record.ContentType == TLSContentType.Handshake) { // Determine next handshake step TLSHandShakeMessage msg = tlsmsg as TLSHandShakeMessage; if (msg.HandShakeMessageType != HandShakeMessageType.Finished) { AllHandShakeMessages.AppendData(msg.RawBytes); if (SocketClient.ShowDebug == true) { System.Diagnostics.Debug.WriteLine("AllHandShakeMessages, adding record of length {0}, Length is now {1}", record.RawSetContent.Length, AllHandShakeMessages.Size); } } else { } HandleHandshakeMessage(msg); } else if (record.ContentType == TLSContentType.Alert) { TLSAlertMessage msg = tlsmsg as TLSAlertMessage; } else if (record.ContentType == TLSContentType.ChangeCipherSpec) { TLSChangeCipherSpecMessage msg = tlsmsg as TLSChangeCipherSpecMessage; HandleChangeCipherSpecMessage(msg); } else if (record.ContentType == TLSContentType.Application) { // decrypt, add to ApplicationDataReturned TLSApplicationMessage msg = tlsmsg as TLSApplicationMessage; ApplicationDataReturned.Add(msg.ApplicationData); } } return(ApplicationDataReturned); }
void ParseContentForRecords(byte [] bContent) { Messages.Clear(); uint nIndexAt = 0; while (nIndexAt < bContent.Length) // Read all the sub records of type ContentType in this TLSRecord { if (ContentType == TLSContentType.Handshake) { // Determine next handshake step TLSHandShakeMessage msg = new TLSHandShakeMessage(); uint nRead = msg.ReadFromArray(bContent, (int)nIndexAt); if (nRead == 0) { break; } Messages.Add(msg); nIndexAt += nRead; } else if (ContentType == TLSContentType.Alert) { TLSAlertMessage msg = new TLSAlertMessage(); uint nRead = msg.ReadFromArray(bContent, (int)nIndexAt); if (nRead == 0) { break; } Messages.Add(msg); nIndexAt += nRead; } else if (ContentType == TLSContentType.ChangeCipherSpec) { TLSChangeCipherSpecMessage msg = new TLSChangeCipherSpecMessage(); uint nRead = msg.ReadFromArray(bContent, (int)nIndexAt); if (nRead == 0) { break; } Messages.Add(msg); nIndexAt += nRead; } else if (ContentType == TLSContentType.Application) { // decrypt, add to ApplicationDataReturned TLSApplicationMessage msg = new TLSApplicationMessage(); uint nRead = msg.ReadFromArray(bContent, (int)nIndexAt); if (nRead == 0) { break; } Messages.Add(msg); nIndexAt += nRead; } else { break; } } }