TLSMessage ReadPlainText(ContentType type, ProtocolVersion ver, int offset, ushort length) { switch (type) { case ContentType.Alert: return(new Alert((AlertLevel)_recvBuffer[offset], (AlertDescription)_recvBuffer[offset + 1])); case ContentType.ChangeCipherSpec: _recvSeq = 0; return(ChangeCipherSpec.Instance); case ContentType.Handshake: HandshakeType htype = (HandshakeType)_recvBuffer[offset]; uint hlength = BitConverterBE.ReadUInt24(_recvBuffer, offset + 1); if (hlength > MaxFragmentSize - 9) { throw new Exception(); // TODO } if (htype == HandshakeType.Finished) { ComputeHandshakeHash(false); } byte[] temp = new byte[length]; Buffer.BlockCopy(_recvBuffer, offset, temp, 0, length); _handshakePackets.Add(temp); return(Handshake.HandshakeMessage.Create(ver, htype, _recvBuffer, offset + 4, hlength)); case ContentType.ApplicationData: return(new ApplicationData(_recvBuffer, offset, length)); default: throw new Exception(); } }
private HandshakeMessage createClientHandshakeMessage(HandshakeType type) { switch (type) { case HandshakeType.CertificateVerify: return(new TlsClientCertificateVerify(this.context)); case HandshakeType.ClientKeyExchange: return(new TlsClientKeyExchange(this.context)); default: if (type == HandshakeType.ClientHello) { return(new TlsClientHello(this.context)); } if (type != HandshakeType.Certificate) { throw new InvalidOperationException("Unknown client handshake message type: " + type.ToString()); } return(new TlsClientCertificate(this.context)); case HandshakeType.Finished: return(new TlsClientFinished(this.context)); } }
protected override void ProcessHandshakeMessage(TlsStream handMsg) { HandshakeType type = (HandshakeType)handMsg.ReadByte(); int count = handMsg.ReadInt24(); byte[] buffer = (byte[])null; if (count > 0) { buffer = new byte[count]; handMsg.Read(buffer, 0, count); } HandshakeMessage handshakeMessage = this.createServerHandshakeMessage(type, buffer); handshakeMessage?.Process(); this.Context.LastHandshakeMsg = type; if (handshakeMessage == null) { return; } handshakeMessage.Update(); this.Context.HandshakeMessages.WriteByte((byte)type); this.Context.HandshakeMessages.WriteInt24(count); if (count <= 0) { return; } this.Context.HandshakeMessages.Write(buffer, 0, buffer.Length); }
public override HandshakeMessage GetMessage(HandshakeType type) { // Create and process the record message HandshakeMessage msg = this.createServerHandshakeMessage(type); return(msg); }
private void OnHelloRequest(OutgoingMessageBag outgoingMessages) { //客户端根据配置决定握手层版本号 SubProtocolVersion = GetSubProtocol(); var clientHelloMessage = SubProtocolVersion.SequenceEqual(Constants.V3_3) ? new V0_2.HandshakeMessages.ClientHelloMessage() : new ClientHelloMessage(); clientHelloMessage.RandomNumber = new byte[RandomNumberLength]; clientHelloMessage.SessionID = SessionID; m_rng.GetBytes(clientHelloMessage.RandomNumber); ////TODO: 测试 //string random = "5e c2 54 f6 fa cc f1 40 be ec 3b 43 44 1c 72 c3 25 ed 43 7a 5d cf a2 17 33 26 94 48 f7 cb 34 f9"; //clientHelloMessage.RandomNumber = random.ConvertHexToByteArray(); SecurityParameters.ClientRandom = clientHelloMessage.RandomNumber; clientHelloMessage.CipherSuites = AllowedCipherSuites; NetMQMessage outgoingMessage = clientHelloMessage.ToNetMQMessage(); HashLocalAndRemote(outgoingMessage); //第一个record的seqnum从0开始 outgoingMessages.AddHandshakeMessage(outgoingMessage); m_lastSentMessage = HandshakeType.ClientHello; }
protected override bool VerifyMessage (HandshakeType type) { switch (type) { case HandshakeType.ServerHello: return hello == null; case HandshakeType.Certificate: return hello != null && certificate == null && certificateRequest == null && done == null; case HandshakeType.ServerKeyExchange: if (!UsingServerKeyExchange) return false; return hello != null && certificate != null && certificateRequest == null && done == null; case HandshakeType.CertificateRequest: if (UsingServerKeyExchange && serverKeyExchange == null) return false; return hello != null && certificate != null && certificateRequest == null && done == null; case HandshakeType.ServerHelloDone: if (UsingServerKeyExchange && serverKeyExchange == null) return false; return hello != null && done == null; default: return false; } }
/// <summary> /// Reads the server response from the underlying inner stream. /// </summary> void ReadServerResponse() { // We get a base64-encoded ASCII string back from the server. string base64 = ReadLine(innerStream); HandshakeType type = HandshakeType.HandshakeInProgress; byte[] decoded; try { // Strip off "+ " continuation command; IMAP and POP3 both use this syntax // whereas SMTP uses "334 ". base64 = Regex.Replace(base64, @"^(\+|334)\s", String.Empty); decoded = Convert.FromBase64String(base64); } catch (FormatException) { // If the server didn't respond with base64-data, something must have gone // wrong and we should gracefully shut down. type = HandshakeType.HandshakeError; decoded = errorCode; } // Prepare a new handshake to hand to the NegotiateStream instance. Handshake hs = new Handshake(type, (ushort)decoded.Length); receivedData = new ByteBuilder() .Append(hs.Serialize()) .Append(decoded) .ToArray(); receivedConsumed = 0; }
/// <summary> /// Prevents a default instance of the <see cref="NextProtocolNegotiationMessage"/> class from being created. /// </summary> /// <param name="type">The message type.</param> /// <param name="selectedProtocol">The selected during NPN protocol.</param> public NextProtocolNegotiationMessage(HandshakeType type, string selectedProtocol) : base(type, null) { this.selectedProtocol = selectedProtocol; this.padding = this.CalcPadding(this.selectedProtocol); this.fragment = this.FormByteFragment(); }
public static HandshakeMessage ReadMessage (TlsContext context, HandshakeType handshakeType, TlsBuffer incoming) { HandshakeMessage message; switch (handshakeType) { case HandshakeType.HelloRequest: message = new TlsHelloRequest (); break; case HandshakeType.ServerHello: return new TlsServerHello (context, incoming); case HandshakeType.Certificate: return new TlsCertificate (incoming); case HandshakeType.ServerHelloDone: message = new TlsServerHelloDone (); break; case HandshakeType.Finished: return new TlsFinished (incoming); case HandshakeType.ClientHello: return new TlsClientHello (context, incoming); case HandshakeType.ClientKeyExchange: return new TlsClientKeyExchange (context, incoming); case HandshakeType.CertificateRequest: return new TlsCertificateRequest (context.NegotiatedProtocol, incoming); case HandshakeType.CertificateVerify: return new TlsCertificateVerify (context.NegotiatedProtocol, incoming); case HandshakeType.ServerKeyExchange: return new TlsServerKeyExchange (context, incoming); default: throw new TlsException (AlertDescription.UnexpectedMessage, "Unknown server handshake message received: {0}", handshakeType); } message.Read (incoming); return message; }
protected override void ProcessHandshakeMessage(TlsStream handMsg) { HandshakeType handshakeType = (HandshakeType)handMsg.ReadByte(); HandshakeMessage handshakeMessage = null; int num = handMsg.ReadInt24(); byte[] array = null; if (num > 0) { array = new byte[num]; handMsg.Read(array, 0, num); } handshakeMessage = createServerHandshakeMessage(handshakeType, array); handshakeMessage?.Process(); base.Context.LastHandshakeMsg = handshakeType; if (handshakeMessage != null) { handshakeMessage.Update(); base.Context.HandshakeMessages.WriteByte((byte)handshakeType); base.Context.HandshakeMessages.WriteInt24(num); if (num > 0) { base.Context.HandshakeMessages.Write(array, 0, array.Length); } } }
public static FragmentBody Factory(HandshakeType type, byte[] bodyBytes) { if (type == HandshakeType.Client_Hello) { return(new ClientHello(bodyBytes)); } else if (type == HandshakeType.Certificate) { return(new Certificate(bodyBytes)); } else if (type == HandshakeType.Client_Key_Exchange) { return(new ClientKeyExchange(bodyBytes)); } else if (type == HandshakeType.Certificate_Verify) { return(new CertificateVerify(bodyBytes)); } else if (type == HandshakeType.Finished) { return(new Finished(bodyBytes)); } throw new Exception($"unhandled HandshakeType {type}"); }
public void CheckPrePhase(HandshakeType type) { if (Handshake != type) { throw new NetSecureException("错误的安全通信建立顺序"); } }
private HandshakeMessage createClientHandshakeMessage( HandshakeType type, byte[] buffer) { switch (type) { case HandshakeType.ClientHello: return(new TlsClientHello(this.context, buffer)); case HandshakeType.Certificate: return(new TlsClientCertificate(this.context, buffer)); case HandshakeType.ClientKeyExchange: return(new TlsClientKeyExchange(this.context, buffer)); case HandshakeType.CertificateVerify: return(new TlsClientCertificateVerify(this.context, buffer)); case HandshakeType.Finished: return(new TlsClientFinished(this.context, buffer)); default: throw new TlsException( AlertDescription.UnexpectedMessage, String.Format(CultureInfo.CurrentUICulture, "Unknown server handshake message received ({0})", type.ToString())); } }
public Handshake(HandshakeType type, ushort payloadSize) { MessageId = type; PayloadSize = payloadSize; MajorVersion = Majorversion; MinorVersion = Minorversion; }
protected override void ProcessHandshakeMessage(TlsStream handMsg) { HandshakeType handshakeType = (HandshakeType)handMsg.ReadByte(); HandshakeMessage message = null; // Read message length int length = handMsg.ReadInt24(); // Read message data byte[] data = new byte[length]; handMsg.Read(data, 0, length); // Create and process the server message message = this.createClientHandshakeMessage(handshakeType, data); message.Process(); // Update the last handshake message this.Context.LastHandshakeMsg = handshakeType; // Update session if (message != null) { message.Update(); this.Context.HandshakeMessages.WriteByte((byte)handshakeType); this.Context.HandshakeMessages.WriteInt24(length); this.Context.HandshakeMessages.Write(data, 0, data.Length); } }
private HandshakeMessage createClientHandshakeMessage( HandshakeType type, byte[] buffer) { HandshakeType handshakeType = type; switch (handshakeType) { case HandshakeType.CertificateVerify: return((HandshakeMessage) new TlsClientCertificateVerify(this.context, buffer)); case HandshakeType.ClientKeyExchange: return((HandshakeMessage) new TlsClientKeyExchange(this.context, buffer)); case HandshakeType.Finished: return((HandshakeMessage) new TlsClientFinished(this.context, buffer)); default: if (handshakeType == HandshakeType.ClientHello) { return((HandshakeMessage) new TlsClientHello(this.context, buffer)); } if (handshakeType == HandshakeType.Certificate) { return((HandshakeMessage) new TlsClientCertificate(this.context, buffer)); } throw new TlsException(AlertDescription.UnexpectedMessage, string.Format((IFormatProvider)CultureInfo.CurrentUICulture, "Unknown server handshake message received ({0})", (object)type.ToString())); } }
private HandshakeMessage createServerHandshakeMessage( HandshakeType type) { switch (type) { case HandshakeType.HelloRequest: this.SendRecord(HandshakeType.ClientHello); return(null); case HandshakeType.ServerHello: return(new TlsServerHello(this.context)); case HandshakeType.Certificate: return(new TlsServerCertificate(this.context)); case HandshakeType.ServerKeyExchange: return(new TlsServerKeyExchange(this.context)); case HandshakeType.CertificateRequest: return(new TlsServerCertificateRequest(this.context)); case HandshakeType.ServerHelloDone: return(new TlsServerHelloDone(this.context)); case HandshakeType.Finished: return(new TlsServerFinished(this.context)); default: throw new InvalidOperationException("Unknown server handshake message type: " + type.ToString()); } }
private void AddFinished(OutgoingMessageBag outgoingMessages) { m_localHash.TransformFinalBlock(EmptyArray <byte> .Instance, 0, 0); byte[] seed = m_localHash.Hash; #if NET40 m_localHash.Dispose(); #endif m_localHash = null; var label = SecurityParameters.Entity == ConnectionEnd.Server ? ServerFinishedLabel : ClientFinshedLabel; var finishedMessage = SubProtocolVersion.SequenceEqual(Constants.V3_3)? new V0_2.HandshakeMessages.FinishedMessage(): new FinishedMessage(); finishedMessage.VerifyData = PRF.Get(SecurityParameters.MasterSecret, label, seed, FinishedMessage.VerifyDataLength); #if DEBUG Debug.WriteLine("[verify_data]:" + BitConverter.ToString(finishedMessage.VerifyData)); #endif NetMQMessage outgoingMessage = finishedMessage.ToNetMQMessage(); outgoingMessages.AddHandshakeMessage(outgoingMessage); m_lastSentMessage = HandshakeType.Finished; if (SecurityParameters.Entity == ConnectionEnd.Client) { HashRemote(outgoingMessage); } }
/// <summary> /// Creates a new instance of the Handshake class using the specified type /// and payload size. /// </summary> /// <param name="type">The type of handshake.</param> /// <param name="payloadSize">The size, in bytes, of the payload following /// the handshake header.</param> public Handshake(HandshakeType type, ushort payloadSize) { MessageId = type; PayloadSize = payloadSize; MajorVersion = majorVersion; MinorVersion = minorVersion; }
private void AddFinished(OutgoingMessageBag outgoingMessages) { m_localHash.TransformFinalBlock(new byte[0], 0, 0); byte[] seed = m_localHash.Hash; m_localHash.Dispose(); m_localHash = null; string label; if (SecurityParameters.Entity == ConnectionEnd.Server) { label = ServerFinishedLabel; } else { label = ClientFinshedLabel; } FinishedMessage finishedMessage = new FinishedMessage(); finishedMessage.VerifyData = PRF.Get(SecurityParameters.MasterSecret, label, seed, FinishedMessage.VerifyDataLength); NetMQMessage outgoingMessage = finishedMessage.ToNetMQMessage(); outgoingMessages.AddHandshakeMessage(outgoingMessage); m_lastSentMessage = HandshakeType.Finished; if (SecurityParameters.Entity == ConnectionEnd.Client) { HashRemote(outgoingMessage); } }
protected override bool VerifyMessage(HandshakeType type) { switch (type) { case HandshakeType.ServerHello: return(hello == null); case HandshakeType.Certificate: return(hello != null && certificate == null && certificateRequest == null && done == null); case HandshakeType.ServerKeyExchange: if (!UsingServerKeyExchange) { return(false); } return(hello != null && certificate != null && certificateRequest == null && done == null); case HandshakeType.CertificateRequest: if (UsingServerKeyExchange && serverKeyExchange == null) { return(false); } return(hello != null && certificate != null && certificateRequest == null && done == null); case HandshakeType.ServerHelloDone: if (UsingServerKeyExchange && serverKeyExchange == null) { return(false); } return(hello != null && done == null); default: return(false); } }
private void ProcessHandshake() { bool read; do { read = false; /* * We need the first 4 bytes, they contain type and length of * the message. */ if (handshakeQueue.Available >= 4) { byte[] beginning = new byte[4]; handshakeQueue.Read(beginning, 0, 4, 0); MemoryStream bis = new MemoryStream(beginning, false); HandshakeType type = (HandshakeType)TlsUtilities.ReadUint8(bis); int len = TlsUtilities.ReadUint24(bis); /* * Check if we have enough bytes in the buffer to read * the full message. */ if (handshakeQueue.Available >= (len + 4)) { /* * Read the message. */ byte[] buf = new byte[len]; handshakeQueue.Read(buf, 0, len, 4); handshakeQueue.RemoveData(len + 4); /* * RFC 2246 7.4.9. The value handshake_messages includes all * handshake messages starting at client hello up to, but not * including, this finished message. [..] Note: [Also,] Hello Request * messages are omitted from handshake hashes. */ switch (type) { case HandshakeType.hello_request: case HandshakeType.finished: break; default: rs.UpdateHandshakeData(beginning, 0, 4); rs.UpdateHandshakeData(buf, 0, len); break; } /* * Now, parse the message. */ ProcessHandshakeMessage(type, buf); read = true; } } }while (read); }
/// <summary> /// Decodes the handshake. /// </summary> /// <param name="context"></param> /// <param name="input"></param> /// <param name="output"></param> protected override void Decode(IChannelHandlerContext context, IByteBuffer input, List <object> output) { if (!input.IsReadable()) { return; } HandshakeType type = Handshake.GetHandshakeType(input.ReadByte()); if (type == HandshakeType.NONE) { return; } switch (type) { case HandshakeType.UPDATE_CONNECTION: int version = input.ReadInt(); output.Add(new HandshakeRequest(version)); break; case HandshakeType.LOGIN_CONNECTION: context.Channel.WriteAndFlushAsync(new HandshakeResponse(type, ConnectionMessage.SUCCESSFUL)); break; } }
/// <summary> /// 解析Certificate格式 /// </summary> /// <param name="handshakeType"></param> /// <param name="bytes"></param> /// <param name="sslMessage"></param> private static void GetCertificateLayer(HandshakeType handshakeType, byte[] bytes, ref int offset, NetMQMessage sslMessage) { int length = GetHandShakeContentLength(bytes, ref offset, sslMessage); int start = offset; byte[] certificatesLengthBytes = new byte[Constants.CERTIFICATE_LENGTH]; //get hand shake content length Buffer.BlockCopy(bytes, offset, certificatesLengthBytes, 0, Constants.CERTIFICATE_LENGTH); sslMessage.Append(certificatesLengthBytes); start += Constants.CERTIFICATE_LENGTH; int certificatesLength = BitConverter.ToInt32(new byte[] { certificatesLengthBytes[2], certificatesLengthBytes[1], certificatesLengthBytes[0], 0 }, 0); //目前只有一个证书 //while (start < bytes.Length) //{ byte[] certificateLengthBytes = new byte[Constants.CERTIFICATE_LENGTH]; //get hand shake content length Buffer.BlockCopy(bytes, start, certificateLengthBytes, 0, Constants.CERTIFICATE_LENGTH); sslMessage.Append(certificateLengthBytes); //暂时只加载第一个证书 int certificateLength = BitConverter.ToInt32(new byte[] { certificateLengthBytes[2], certificateLengthBytes[1], certificateLengthBytes[0], 0 }, 0); start += Constants.CERTIFICATE_LENGTH; byte[] certificateBytes = new byte[certificateLength]; //get Cipher Suites Length version Buffer.BlockCopy(bytes, start, certificateBytes, 0, certificateLength); sslMessage.Append(certificateBytes); //} //加上总长度,多个证书不加载后面的证书, //length包含了Constants.CERTIFICATE_LENGTH,前面为了取证书偏移了一次。 offset += length; }
private void AddServerHelloMessage(OutgoingMessageBag outgoingMessages, CipherSuite[] cipherSuites) { var serverHelloMessage = new ServerHelloMessage { RandomNumber = new byte[RandomNumberLength] }; m_rng.GetBytes(serverHelloMessage.RandomNumber); SecurityParameters.ServerRandom = serverHelloMessage.RandomNumber; // in case there is no match the server will return this default serverHelloMessage.CipherSuite = CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA; foreach (var cipherSuite in cipherSuites) { if (AllowedCipherSuites.Contains(cipherSuite)) { serverHelloMessage.CipherSuite = cipherSuite; SetCipherSuite(cipherSuite); break; } } NetMQMessage outgoingMessage = serverHelloMessage.ToNetMQMessage(); HashLocalAndRemote(outgoingMessage); outgoingMessages.AddHandshakeMessage(outgoingMessage); m_lastSentMessage = HandshakeType.ServerHello; }
private void AddFinished(OutgoingMessageBag outgoingMessages) { m_localHash.TransformFinalBlock(EmptyArray <byte> .Instance, 0, 0); byte[] seed = m_localHash.Hash; m_localHash.Dispose(); m_localHash = null; var label = SecurityParameters.Entity == ConnectionEnd.Server ? ServerFinishedLabel : ClientFinshedLabel; var finishedMessage = new FinishedMessage { VerifyData = PRF.Get(SecurityParameters.MasterSecret, label, seed, FinishedMessage.VerifyDataLength) }; NetMQMessage outgoingMessage = finishedMessage.ToNetMQMessage(); outgoingMessages.AddHandshakeMessage(outgoingMessage); m_lastSentMessage = HandshakeType.Finished; if (SecurityParameters.Entity == ConnectionEnd.Client) { HashRemote(outgoingMessage); } }
private HandshakeMessage Read(HandshakeType type, byte[] body) { switch (type) { case HandshakeType.ClientHello: return(ClientHelloMessage.Read(body)); case HandshakeType.ServerHello: return(ServerHelloMessage.Read(body)); case HandshakeType.Certificate: return(CertificateMessage.Read(body, b => new X509Reader(_publicKeyReaderRegistry, b))); case HandshakeType.ServerKeyExchange: return(new ServerKeyExchangeMessage(body)); case HandshakeType.ServerHelloDone: return(ServerHelloDoneMessage.Read(body)); case HandshakeType.ClientKeyExchange: return(new ClientKeyExchangeMessage(body)); case HandshakeType.Finished: return(ReadFinished(body)); default: throw new ArgumentOutOfRangeException(nameof(type), type, null); } }
public override HandshakeMessage GetMessage(HandshakeType type) { // Create and process the record message HandshakeMessage msg = this.createServerHandshakeMessage(type); return msg; }
public virtual void SendRecord(HandshakeType type) { IAsyncResult ar = this.BeginSendRecord(type, null, null); this.EndSendRecord(ar); }
/// <summary> /// ContentType (1,handshake:22) /// ProtocolVersion(2:0303) /// 握手协议长度:(2) /// 握手协议数据 /// HandShakeType(finished:20) /// VerifyData /// </summary> /// <param name="handshakeType"></param> /// <param name="bytes"></param> /// <param name="sslMessage"></param> private static void GetFinishLayer(HandshakeType handshakeType, byte[] bytes, ref int offset, NetMQMessage sslMessage) { byte[] verifyDataBytes = new byte[bytes.Length - offset]; //get master key length Buffer.BlockCopy(bytes, offset, verifyDataBytes, 0, bytes.Length - offset); sslMessage.Append(verifyDataBytes); offset += verifyDataBytes.Length; }
private static void GetServerHelloDoneLayer(HandshakeType handshakeType, byte[] bytes, ref int offset, NetMQMessage sslMessage) { byte[] handShakeContentLengthBytes = new byte[Constants.HAND_SHAKE_CONTENT_LENGTH]; //get hand shake content length Buffer.BlockCopy(bytes, offset, handShakeContentLengthBytes, 0, Constants.HAND_SHAKE_CONTENT_LENGTH); sslMessage.Append(handShakeContentLengthBytes); offset += Constants.HAND_SHAKE_CONTENT_LENGTH; }
public HandshakeMessage( Context context, HandshakeType handshakeType, byte[] data) : base(data) { this.context = context; this.handshakeType = handshakeType; }
private static HandshakeType GetHandshakeType(byte[] bytes, ref int offset, NetMQMessage sslMessage) { HandshakeType handshakeType = (HandshakeType)bytes[offset]; sslMessage.Append(new[] { (byte)handshakeType }); offset += Constants.HAND_SHAKE_TYPE; return(handshakeType); }
public HandshakeMessage( Context context, HandshakeType handshakeType, byte[] data) : base(data) { Context = context; HandshakeType = handshakeType; }
public HandshakeMessage( Context context, HandshakeType handshakeType, ContentType contentType) { Context = context; HandshakeType = handshakeType; ContentType = contentType; }
void CheckType(HandshakeType type) { if (type == HandshakeType.ServerHelloDone) HasServerHelloDone = true; else if (type == HandshakeType.Finished) _hasFinished = true; else if (type == HandshakeType.HelloRequest) _hasHelloRequest = true; }
protected override bool VerifyMessage (HandshakeType type) { switch (type) { case HandshakeType.ClientHello: return hello == null; default: return false; } }
private void AddServerHelloDone(OutgoingMessageBag outgoingMessages) { var serverHelloDoneMessage = new ServerHelloDoneMessage(); NetMQMessage outgoingMessage = serverHelloDoneMessage.ToNetMQMessage(); HashLocalAndRemote(outgoingMessage); outgoingMessages.AddHandshakeMessage(outgoingMessage); m_lastSentMessage = HandshakeType.ServerHelloDone; }
public HandshakeMessage( Context context, HandshakeType handshakeType, ContentType contentType) : base() { this.context = context; this.handshakeType = handshakeType; this.contentType = contentType; }
protected override bool VerifyMessage (HandshakeType type) { switch (type) { case HandshakeType.ChanceCipherSpec: return changeCipher == null; case HandshakeType.Finished: return changeCipher != null && finished == null; default: return false; } }
private void UpdateVerify(HandshakeType type, uint length, byte[] body) { if (type == HandshakeType.Finished) { state.ComputeHandshakeVerify(); } state.UpdateHandshakeVerify(new[] {(byte) type}, 0, 1); state.UpdateHandshakeVerify(EndianBitConverter.Big.GetBytes(length), 1, 3); state.UpdateHandshakeVerify(body, 0, body.Length); }
public override void SendRecord(HandshakeType type) { // Create the record message HandshakeMessage msg = this.createServerHandshakeMessage(type); msg.Process(); // Write record this.SendRecord(msg.ContentType, msg.EncodeMessage()); // Update session msg.Update(); // Reset message contents msg.Reset(); }
private HandshakeMessage Read(HandshakeType type, byte[] body) { switch (type) { case HandshakeType.ClientHello: return ClientHelloMessage.Read(state, body); case HandshakeType.ClientKeyExchange: return state.KeyExchange.ReadClientKeyExchange(body); case HandshakeType.Finished: return FinishedHandshakeMessage.Read(state, body); default: throw new ArgumentOutOfRangeException(nameof(type), type, null); } }
protected HelloMessage(HandshakeType type, TlsVersion version, byte[] randomBytes, byte[] sessionId, HelloExtension[] extensions) : base(type) { Version = version; SecurityAssert.NotNull(randomBytes); SecurityAssert.SAssert(randomBytes.Length == 32); RandomBytes = randomBytes; SecurityAssert.NotNull(sessionId); SecurityAssert.SAssert(sessionId.Length >= 0 && sessionId.Length <= 32); SessionId = sessionId; SecurityAssert.NotNull(extensions); SecurityAssert.SAssert(extensions.Length >= 0 && extensions.Length <= 0xFFFF); Extensions = extensions; }
protected override bool VerifyMessage (HandshakeType type) { switch (type) { case HandshakeType.ClientKeyExchange: return keyExchange == null; case HandshakeType.Certificate: return keyExchange == null && certificate == null; case HandshakeType.ChanceCipherSpec: return keyExchange != null && cipherSpec == null; case HandshakeType.Finished: return cipherSpec != null && finished == null; case HandshakeType.CertificateVerify: return keyExchange != null && certificate != null && certificateVerify == null && finished == null; default: return false; } }
protected override HandshakeMessage CreateMessage (HandshakeType type, TlsBuffer incoming) { if (type != HandshakeType.ClientHello) throw new TlsException (AlertDescription.UnexpectedMessage); if (Renegotiating) { var flags = Config.RenegotiationFlags; if ((flags & RenegotiationFlags.DisallowRenegotiation) != 0) throw new TlsException (AlertDescription.HandshakeFailure, "Renegotiation not allowed."); if (!Session.SecureRenegotiation) throw new TlsException (AlertDescription.HandshakeFailure, "Renegotiation not allowed."); } StartHandshake (); return base.CreateMessage (type, incoming); }
public override void SendRecord(HandshakeType type) { // Create and process the record message HandshakeMessage msg = this.createClientHandshakeMessage(type); msg.Process(); DebugHelper.WriteLine(">>>> Write handshake record ({0}|{1})", context.Protocol, msg.ContentType); // Write record this.SendRecord(msg.ContentType, msg.EncodeMessage()); // Update session msg.Update(); // Reset message contents msg.Reset(); }
public virtual HandshakeMessage GetMessage(HandshakeType type) { throw new NotSupportedException(); }
public IAsyncResult BeginSendRecord(HandshakeType handshakeType, AsyncCallback callback, object state) { HandshakeMessage msg = this.GetMessage(handshakeType); msg.Process(); DebugHelper.WriteLine(">>>> Write handshake record ({0}|{1})", context.Protocol, msg.ContentType); SendRecordAsyncResult internalResult = new SendRecordAsyncResult(callback, state, msg); this.BeginSendRecord(msg.ContentType, msg.EncodeMessage(), new AsyncCallback(InternalSendRecordCallback), internalResult); return internalResult; }
private void AddServerHelloDone(OutgoingMessageBag outgoingMessages) { ServerHelloDoneMessage serverHelloDoneMessage = new ServerHelloDoneMessage(); NetMQMessage outgoingMessage = serverHelloDoneMessage.ToNetMQMessage(); HashLocalAndRemote(outgoingMessage); outgoingMessages.AddHandshakeMessage(outgoingMessage); m_lastSentMessage = HandshakeType.ServerHelloDone; }
public HandshakeMessage(HandshakeType type, byte[] bytes) { this.type = type; this.fragment = bytes; }
private void ProcessHandshakeMessage(HandshakeType type, byte[] buf) { MemoryStream inStr = new MemoryStream(buf, false); /* * Check the type. */ switch (type) { case HandshakeType.certificate: { switch (connection_state) { case CS_SERVER_HELLO_RECEIVED: { // Parse the Certificate message and send to cipher suite Certificate serverCertificate = Certificate.Parse(inStr); AssertEmpty(inStr); this.keyExchange.ProcessServerCertificate(serverCertificate); this.authentication = tlsClient.GetAuthentication(); this.authentication.NotifyServerCertificate(serverCertificate); break; } default: this.FailWithError(AlertLevel.fatal, AlertDescription.unexpected_message); break; } connection_state = CS_SERVER_CERTIFICATE_RECEIVED; break; } case HandshakeType.finished: switch (connection_state) { case CS_SERVER_CHANGE_CIPHER_SPEC_RECEIVED: /* * Read the checksum from the finished message, it has always 12 bytes. */ byte[] serverVerifyData = new byte[12]; TlsUtilities.ReadFully(serverVerifyData, inStr); AssertEmpty(inStr); /* * Calculate our own checksum. */ byte[] expectedServerVerifyData = TlsUtilities.PRF( securityParameters.masterSecret, "server finished", rs.GetCurrentHash(), 12); /* * Compare both checksums. */ if (!Arrays.ConstantTimeAreEqual(expectedServerVerifyData, serverVerifyData)) { /* * Wrong checksum in the finished message. */ this.FailWithError(AlertLevel.fatal, AlertDescription.handshake_failure); } connection_state = CS_DONE; /* * We are now ready to receive application data. */ this.appDataReady = true; break; default: this.FailWithError(AlertLevel.fatal, AlertDescription.unexpected_message); break; } break; case HandshakeType.server_hello: switch (connection_state) { case CS_CLIENT_HELLO_SEND: /* * Read the server hello message */ TlsUtilities.CheckVersion(inStr, this); /* * Read the server random */ securityParameters.serverRandom = new byte[32]; TlsUtilities.ReadFully(securityParameters.serverRandom, inStr); byte[] sessionID = TlsUtilities.ReadOpaque8(inStr); if (sessionID.Length > 32) { this.FailWithError(AlertLevel.fatal, AlertDescription.illegal_parameter); } this.tlsClient.NotifySessionID(sessionID); /* * Find out which CipherSuite the server has chosen and check that * it was one of the offered ones. */ CipherSuite selectedCipherSuite = (CipherSuite)TlsUtilities.ReadUint16(inStr); if (!ArrayContains(offeredCipherSuites, selectedCipherSuite) || selectedCipherSuite == CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV) { this.FailWithError(AlertLevel.fatal, AlertDescription.illegal_parameter); } this.tlsClient.NotifySelectedCipherSuite(selectedCipherSuite); /* * Find out which CompressionMethod the server has chosen and check that * it was one of the offered ones. */ CompressionMethod selectedCompressionMethod = (CompressionMethod)TlsUtilities.ReadUint8(inStr); if (!ArrayContains(offeredCompressionMethods, selectedCompressionMethod)) { this.FailWithError(AlertLevel.fatal, AlertDescription.illegal_parameter); } this.tlsClient.NotifySelectedCompressionMethod(selectedCompressionMethod); /* * RFC3546 2.2 The extended server hello message format MAY be * sent in place of the server hello message when the client has * requested extended functionality via the extended client hello * message specified in Section 2.1. * ... * Note that the extended server hello message is only sent in response * to an extended client hello message. This prevents the possibility * that the extended server hello message could "break" existing TLS 1.0 * clients. */ /* * TODO RFC 3546 2.3 * If [...] the older session is resumed, then the server MUST ignore * extensions appearing in the client hello, and send a server hello * containing no extensions. */ // ExtensionType -> byte[] IDictionary serverExtensions = Platform.CreateHashtable(); if (inStr.Position < inStr.Length) { // Process extensions from extended server hello byte[] extBytes = TlsUtilities.ReadOpaque16(inStr); MemoryStream ext = new MemoryStream(extBytes, false); while (ext.Position < ext.Length) { ExtensionType extType = (ExtensionType)TlsUtilities.ReadUint16(ext); byte[] extValue = TlsUtilities.ReadOpaque16(ext); // Note: RFC 5746 makes a special case for EXT_RenegotiationInfo if (extType != ExtensionType.renegotiation_info && !clientExtensions.Contains(extType)) { /* * RFC 3546 2.3 * Note that for all extension types (including those defined in * future), the extension type MUST NOT appear in the extended server * hello unless the same extension type appeared in the corresponding * client hello. Thus clients MUST abort the handshake if they receive * an extension type in the extended server hello that they did not * request in the associated (extended) client hello. */ this.FailWithError(AlertLevel.fatal, AlertDescription.unsupported_extension); } if (serverExtensions.Contains(extType)) { /* * RFC 3546 2.3 * Also note that when multiple extensions of different types are * present in the extended client hello or the extended server hello, * the extensions may appear in any order. There MUST NOT be more than * one extension of the same type. */ this.FailWithError(AlertLevel.fatal, AlertDescription.illegal_parameter); } serverExtensions.Add(extType, extValue); } } AssertEmpty(inStr); /* * RFC 5746 3.4. When a ServerHello is received, the client MUST check if it * includes the "renegotiation_info" extension: */ { bool secure_negotiation = serverExtensions.Contains(ExtensionType.renegotiation_info); /* * If the extension is present, set the secure_renegotiation flag * to TRUE. The client MUST then verify that the length of the * "renegotiated_connection" field is zero, and if it is not, MUST * abort the handshake (by sending a fatal handshake_failure * alert). */ if (secure_negotiation) { byte[] renegExtValue = (byte[])serverExtensions[ExtensionType.renegotiation_info]; if (!Arrays.ConstantTimeAreEqual(renegExtValue, CreateRenegotiationInfo(emptybuf))) { this.FailWithError(AlertLevel.fatal, AlertDescription.handshake_failure); } } tlsClient.NotifySecureRenegotiation(secure_negotiation); } if (clientExtensions != null) { tlsClient.ProcessServerExtensions(serverExtensions); } this.keyExchange = tlsClient.GetKeyExchange(); connection_state = CS_SERVER_HELLO_RECEIVED; break; default: this.FailWithError(AlertLevel.fatal, AlertDescription.unexpected_message); break; } break; case HandshakeType.server_hello_done: switch (connection_state) { case CS_SERVER_CERTIFICATE_RECEIVED: case CS_SERVER_KEY_EXCHANGE_RECEIVED: case CS_CERTIFICATE_REQUEST_RECEIVED: // NB: Original code used case label fall-through if (connection_state == CS_SERVER_CERTIFICATE_RECEIVED) { // There was no server key exchange message; check it's OK this.keyExchange.SkipServerKeyExchange(); } AssertEmpty(inStr); connection_state = CS_SERVER_HELLO_DONE_RECEIVED; TlsCredentials clientCreds = null; if (certificateRequest == null) { this.keyExchange.SkipClientCredentials(); } else { clientCreds = this.authentication.GetClientCredentials(certificateRequest); Certificate clientCert; if (clientCreds == null) { this.keyExchange.SkipClientCredentials(); clientCert = Certificate.EmptyChain; } else { this.keyExchange.ProcessClientCredentials(clientCreds); clientCert = clientCreds.Certificate; } SendClientCertificate(clientCert); } /* * Send the client key exchange message, depending on the key * exchange we are using in our CipherSuite. */ SendClientKeyExchange(); connection_state = CS_CLIENT_KEY_EXCHANGE_SEND; if (clientCreds != null && clientCreds is TlsSignerCredentials) { TlsSignerCredentials signerCreds = (TlsSignerCredentials)clientCreds; byte[] md5andsha1 = rs.GetCurrentHash(); byte[] clientCertificateSignature = signerCreds.GenerateCertificateSignature( md5andsha1); SendCertificateVerify(clientCertificateSignature); connection_state = CS_CERTIFICATE_VERIFY_SEND; } /* * Now, we send change cipher state */ byte[] cmessage = new byte[1]; cmessage[0] = 1; rs.WriteMessage(ContentType.change_cipher_spec, cmessage, 0, cmessage.Length); connection_state = CS_CLIENT_CHANGE_CIPHER_SPEC_SEND; /* * Calculate the master_secret */ byte[] pms = this.keyExchange.GeneratePremasterSecret(); securityParameters.masterSecret = TlsUtilities.PRF(pms, "master secret", TlsUtilities.Concat(securityParameters.clientRandom, securityParameters.serverRandom), 48); // TODO Is there a way to ensure the data is really overwritten? /* * RFC 2246 8.1. The pre_master_secret should be deleted from * memory once the master_secret has been computed. */ Array.Clear(pms, 0, pms.Length); /* * Initialize our cipher suite */ rs.ClientCipherSpecDecided(tlsClient.GetCompression(), tlsClient.GetCipher()); /* * Send our finished message. */ byte[] clientVerifyData = TlsUtilities.PRF(securityParameters.masterSecret, "client finished", rs.GetCurrentHash(), 12); MemoryStream bos = new MemoryStream(); TlsUtilities.WriteUint8((byte)HandshakeType.finished, bos); TlsUtilities.WriteOpaque24(clientVerifyData, bos); byte[] message = bos.ToArray(); rs.WriteMessage(ContentType.handshake, message, 0, message.Length); this.connection_state = CS_CLIENT_FINISHED_SEND; break; default: this.FailWithError(AlertLevel.fatal, AlertDescription.handshake_failure); break; } break; case HandshakeType.server_key_exchange: { switch (connection_state) { case CS_SERVER_HELLO_RECEIVED: case CS_SERVER_CERTIFICATE_RECEIVED: { // NB: Original code used case label fall-through if (connection_state == CS_SERVER_HELLO_RECEIVED) { // There was no server certificate message; check it's OK this.keyExchange.SkipServerCertificate(); this.authentication = null; } this.keyExchange.ProcessServerKeyExchange(inStr); AssertEmpty(inStr); break; } default: this.FailWithError(AlertLevel.fatal, AlertDescription.unexpected_message); break; } this.connection_state = CS_SERVER_KEY_EXCHANGE_RECEIVED; break; } case HandshakeType.certificate_request: switch (connection_state) { case CS_SERVER_CERTIFICATE_RECEIVED: case CS_SERVER_KEY_EXCHANGE_RECEIVED: { // NB: Original code used case label fall-through if (connection_state == CS_SERVER_CERTIFICATE_RECEIVED) { // There was no server key exchange message; check it's OK this.keyExchange.SkipServerKeyExchange(); } if (this.authentication == null) { /* * RFC 2246 7.4.4. It is a fatal handshake_failure alert * for an anonymous server to request client identification. */ this.FailWithError(AlertLevel.fatal, AlertDescription.handshake_failure); } int numTypes = TlsUtilities.ReadUint8(inStr); ClientCertificateType[] certificateTypes = new ClientCertificateType[numTypes]; for (int i = 0; i < numTypes; ++i) { certificateTypes[i] = (ClientCertificateType)TlsUtilities.ReadUint8(inStr); } byte[] authorities = TlsUtilities.ReadOpaque16(inStr); AssertEmpty(inStr); IList authorityDNs = Platform.CreateArrayList(); MemoryStream bis = new MemoryStream(authorities, false); while (bis.Position < bis.Length) { byte[] dnBytes = TlsUtilities.ReadOpaque16(bis); // TODO Switch to X500Name when available authorityDNs.Add(X509Name.GetInstance(Asn1Object.FromByteArray(dnBytes))); } this.certificateRequest = new CertificateRequest(certificateTypes, authorityDNs); this.keyExchange.ValidateCertificateRequest(this.certificateRequest); break; } default: this.FailWithError(AlertLevel.fatal, AlertDescription.unexpected_message); break; } this.connection_state = CS_CERTIFICATE_REQUEST_RECEIVED; break; case HandshakeType.hello_request: /* * RFC 2246 7.4.1.1 Hello request * This message will be ignored by the client if the client is currently * negotiating a session. This message may be ignored by the client if it * does not wish to renegotiate a session, or the client may, if it wishes, * respond with a no_renegotiation alert. */ if (connection_state == CS_DONE) { // Renegotiation not supported yet SendAlert(AlertLevel.warning, AlertDescription.no_renegotiation); } break; case HandshakeType.client_key_exchange: case HandshakeType.certificate_verify: case HandshakeType.client_hello: default: // We do not support this! this.FailWithError(AlertLevel.fatal, AlertDescription.unexpected_message); break; } }
private void OnHelloRequest(OutgoingMessageBag outgoingMessages) { ClientHelloMessage clientHelloMessage = new ClientHelloMessage(); clientHelloMessage.RandomNumber = new byte[RandomNumberLength]; m_rng.GetBytes(clientHelloMessage.RandomNumber); SecurityParameters.ClientRandom = clientHelloMessage.RandomNumber; clientHelloMessage.CipherSuites = AllowedCipherSuites; NetMQMessage outgoingMessage = clientHelloMessage.ToNetMQMessage(); HashLocalAndRemote(outgoingMessage); outgoingMessages.AddHandshakeMessage(outgoingMessage); m_lastSentMessage = HandshakeType.ClientHello; }
private void AddServerHelloMessage(OutgoingMessageBag outgoingMessages, CipherSuite[] cipherSuites) { ServerHelloMessage serverHelloMessage = new ServerHelloMessage(); serverHelloMessage.RandomNumber = new byte[RandomNumberLength]; m_rng.GetBytes(serverHelloMessage.RandomNumber); SecurityParameters.ServerRandom = serverHelloMessage.RandomNumber; // in case their is no much the server will return this defaul serverHelloMessage.CipherSuite = CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA; foreach (CipherSuite cipherSuite in cipherSuites) { if (AllowedCipherSuites.Contains(cipherSuite)) { serverHelloMessage.CipherSuite = cipherSuite; SetCipherSuite(cipherSuite); break; } } NetMQMessage outgoingMessage = serverHelloMessage.ToNetMQMessage(); HashLocalAndRemote(outgoingMessage); outgoingMessages.AddHandshakeMessage(outgoingMessage); m_lastSentMessage = HandshakeType.ServerHello; }
public byte[] EncodeHandshakeRecord(HandshakeType handshakeType) { HandshakeMessage msg = this.GetMessage(handshakeType); msg.Process(); var bytes = this.EncodeRecord (msg.ContentType, msg.EncodeMessage ()); msg.Update(); msg.Reset(); return bytes; }
public HandshakeMessage( Context context, HandshakeType handshakeType) : this(context, handshakeType, ContentType.Handshake) { }
/// <summary> /// Handshake with the Audioscrobbler service /// </summary> /// <returns>True if the connection was successful, false otherwise</returns> private static void DoHandshake(bool forceNow_, HandshakeType ReasonForHandshake) { if (_useDebugLog) { Log.Debug("AudioscrobblerBase: Attempting {0} handshake", ReasonForHandshake.ToString()); } // Handle uninitialized username/password. if (username.Length < 1 || password.Length < 1) { Log.Error("AudioscrobblerBase: {0}", "user or password not defined"); workerFailed(ReasonForHandshake, DateTime.MinValue, new Exception("Account details insufficent")); return; } if (!forceNow_ || ReasonForHandshake != HandshakeType.Recover) { // Check whether we had a *successful* handshake recently. if (DateTime.Now < lastHandshake.Add(handshakeInterval)) { string nexthandshake = lastHandshake.Add(handshakeInterval).ToString(); string logmessage = "Next handshake due at " + nexthandshake; if (_useDebugLog) { Log.Debug("AudioscrobblerBase: {0}", logmessage); } workerSuccess(ReasonForHandshake, lastHandshake); return; } } if (ReasonForHandshake != HandshakeType.Init) { if (ReasonForHandshake == HandshakeType.PreRadio) { Log.Warn("AudioscrobblerBase: Disconnected - nevertheless trying radio handshake to listen without submits"); AttemptRadioHandshake(); return; } //else //{ // Log.Warn("AudioscrobblerBase: Disconnected - not attempting {0} handshake", ReasonForHandshake.ToString()); // workerFailed(ReasonForHandshake, DateTime.MinValue, new Exception("Disconnected!")); // return; //} } BackgroundWorker worker = new BackgroundWorker(); worker.DoWork += new DoWorkEventHandler(Worker_TryHandshake); worker.RunWorkerAsync(ReasonForHandshake); }
private static void OnHandshakeSuccessful(HandshakeType ReasonForHandshake, DateTime lastSuccessfulHandshake) { switch (ReasonForHandshake) { case HandshakeType.ChangeUser: LoadSettings(); Log.Info("AudioscrobblerBase: Changed user to {0} - loaded {1} queue items", username, queue.Count); break; case HandshakeType.PreRadio: AttemptRadioHandshake(); break; case HandshakeType.Init: AttemptSubmitNow(); break; case HandshakeType.Submit: AttemptSubmitNow(); break; case HandshakeType.Announce: AttemptAnnounceNow(); break; } }
private static void OnHandshakeFailed(HandshakeType ReasonForHandshake, DateTime lastSuccessfulHandshake, Exception errorReason) { switch (ReasonForHandshake) { case HandshakeType.ChangeUser: Log.Warn("AudioscrobblerBase: {0}", "ChangeUser failed - using previous account"); username = olduser; password = oldpass; break; case HandshakeType.PreRadio: Log.Warn("AudioscrobblerBase: {0}", "Handshake failed - not attempting radio login"); RadioHandshakeError(); break; case HandshakeType.Submit: Log.Warn("AudioscrobblerBase: {0}", "Handshake failed - no submits"); break; case HandshakeType.Init: Log.Warn("AudioscrobblerBase: {0}", "Handshake failed - could not log in"); break; case HandshakeType.Recover: Log.Warn("AudioscrobblerBase: {0}", "Handshake failed - could not recover. Disconnecting..."); Disconnect(); break; case HandshakeType.Announce: Log.Warn("AudioscrobblerBase: {0}", "Handshake failed - not announcing current song"); break; } }