Result ChangeCipherSpecAndFinished() { if (State == TLSSessionState.Client_Finished) { var clienthello_clientfinish = GetHandshakeMessages(); var finishedVerify = _params.Cipher.GetVerifyData("server finished", clienthello_clientfinish); var finishedMessage = new byte[] { 0x14, 0x00, 0x00, 0x0C }.Concat(finishedVerify).ToArray(); var macSeed = Utils.GetMacSeed(_sendSeqNum, (byte)RecordType.Handshake, finishedMessage); var myMac = _params.Cipher.ServerMessageAuthCode(macSeed); var finished = new List <byte>(); finished.AddRange(finishedMessage); finished.AddRange(myMac); var serverIv = Utils.Random(16); var encryptedFinished = _params.Cipher.BulkEncrypt(finished.ToArray(), serverIv); var serverFinishFragment = new Handshakes.EncryptedFragment(serverIv.Concat(encryptedFinished).ToArray()); var changeCipherRecord = new Records.ChangeCipherSpec(); var serverFinishRecord = new Records.Handshake(new[] { serverFinishFragment }); _sendSeqNum++; State = TLSSessionState.Server_Finished; return(new PacketResult(new Records.TLSRecord[] { changeCipherRecord, serverFinishRecord })); } else { return(Result.FatalAlert(AlertDescription.unexpected_message, $"State [{State}] check failed on ChangeCipherSpecAndFinished")); } }
protected virtual Result Record_Handshake(Records.Handshake rec) { var pkts = new List <Records.TLSRecord>(); foreach (var frag in rec.Fragments) { if (frag is Handshakes.Fragment hf) { AppendHandshakeMessages(hf); var res = Fragment_Handshake(hf); if (res != null) { if (res is AlertResult ar) { return(ar); } else if (res is PacketResult hr && hr.Response != null) { pkts.AddRange(hr.Response); } } } else if (frag is Handshakes.EncryptedFragment ehf) { var res = Fragment_EncryptedHandshake(ehf); if (res != null) { if (res is AlertResult ar) { return(ar); } else if (res is PacketResult hr && hr.Response != null) { pkts.AddRange(hr.Response); } } } else { return(Result.FatalAlert(AlertDescription.unexpected_message, $"Unhandled TLS Handshake.Fragment.Type {frag.GetType().Name}")); } } if (pkts.Count > 0) { return(new PacketResult(pkts.ToArray())); } else { return(null); } }