-
-
Save directhex/f8c6e67f551d8a608154 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff -urNad mono-3.2.8.orig/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/ClientRecordProtocol.cs mono-3.2.8/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/ClientRecordProtocol.cs | |
--- mono-3.2.8.orig/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/ClientRecordProtocol.cs 2014-02-19 18:48:31.000000000 +0000 | |
+++ mono-3.2.8/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/ClientRecordProtocol.cs 2015-03-06 15:01:29.810597612 +0000 | |
@@ -129,6 +129,7 @@ | |
HandshakeType type, byte[] buffer) | |
{ | |
ClientContext context = (ClientContext)this.context; | |
+ var last = context.LastHandshakeMsg; | |
switch (type) | |
{ | |
@@ -148,23 +149,44 @@ | |
return null; | |
case HandshakeType.ServerHello: | |
+ if (last != HandshakeType.HelloRequest) | |
+ break; | |
return new TlsServerHello(this.context, buffer); | |
+ // Optional | |
case HandshakeType.Certificate: | |
+ if (last != HandshakeType.ServerHello) | |
+ break; | |
return new TlsServerCertificate(this.context, buffer); | |
+ // Optional | |
case HandshakeType.ServerKeyExchange: | |
- return new TlsServerKeyExchange(this.context, buffer); | |
+ // only for RSA_EXPORT | |
+ if (last == HandshakeType.Certificate && context.Current.Cipher.IsExportable) | |
+ return new TlsServerKeyExchange(this.context, buffer); | |
+ break; | |
+ // Optional | |
case HandshakeType.CertificateRequest: | |
- return new TlsServerCertificateRequest(this.context, buffer); | |
+ if (last == HandshakeType.ServerKeyExchange || last == HandshakeType.Certificate) | |
+ return new TlsServerCertificateRequest(this.context, buffer); | |
+ break; | |
case HandshakeType.ServerHelloDone: | |
- return new TlsServerHelloDone(this.context, buffer); | |
+ if (last == HandshakeType.CertificateRequest || last == HandshakeType.Certificate || last == HandshakeType.ServerHello) | |
+ return new TlsServerHelloDone(this.context, buffer); | |
+ break; | |
case HandshakeType.Finished: | |
- return new TlsServerFinished(this.context, buffer); | |
- | |
+ // depends if a full (ServerHelloDone) or an abbreviated handshake (ServerHello) is being done | |
+ bool check = context.AbbreviatedHandshake ? (last == HandshakeType.ServerHello) : (last == HandshakeType.ServerHelloDone); | |
+ // ChangeCipherSpecDone is not an handshake message (it's a content type) but still needs to be happens before finished | |
+ if (check && context.ChangeCipherSpecDone) { | |
+ context.ChangeCipherSpecDone = false; | |
+ return new TlsServerFinished (this.context, buffer); | |
+ } | |
+ break; | |
+ | |
default: | |
throw new TlsException( | |
AlertDescription.UnexpectedMessage, | |
@@ -172,6 +194,7 @@ | |
"Unknown server handshake message received ({0})", | |
type.ToString())); | |
} | |
+ throw new TlsException (AlertDescription.HandshakeFailiure, String.Format ("Protocol error, unexpected protocol transition from {0} to {1}", last, type)); | |
} | |
#endregion | |
diff -urNad mono-3.2.8.orig/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/Context.cs mono-3.2.8/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/Context.cs | |
--- mono-3.2.8.orig/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/Context.cs 2014-02-19 18:51:55.000000000 +0000 | |
+++ mono-3.2.8/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/Context.cs 2015-03-06 15:01:29.810597612 +0000 | |
@@ -122,6 +122,8 @@ | |
set { this.protocolNegotiated = value; } | |
} | |
+ public bool ChangeCipherSpecDone { get; set; } | |
+ | |
public SecurityProtocolType SecurityProtocol | |
{ | |
get | |
diff -urNad mono-3.2.8.orig/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/RecordProtocol.cs mono-3.2.8/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/RecordProtocol.cs | |
--- mono-3.2.8.orig/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/RecordProtocol.cs 2014-02-19 18:51:55.000000000 +0000 | |
+++ mono-3.2.8/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/RecordProtocol.cs 2015-03-06 15:01:29.810597612 +0000 | |
@@ -88,6 +88,8 @@ | |
} else { | |
ctx.StartSwitchingSecurityParameters (false); | |
} | |
+ | |
+ ctx.ChangeCipherSpecDone = true; | |
} | |
public virtual HandshakeMessage GetMessage(HandshakeType type) | |
@@ -348,9 +350,6 @@ | |
// Try to read the Record Content Type | |
int type = internalResult.InitialBuffer[0]; | |
- // Set last handshake message received to None | |
- this.context.LastHandshakeMsg = HandshakeType.ClientHello; | |
- | |
ContentType contentType = (ContentType)type; | |
byte[] buffer = this.ReadRecordBuffer(type, record); | |
if (buffer == null) | |
diff -urNad mono-3.2.8.orig/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/ServerRecordProtocol.cs mono-3.2.8/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/ServerRecordProtocol.cs | |
--- mono-3.2.8.orig/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/ServerRecordProtocol.cs 2014-02-19 18:48:31.000000000 +0000 | |
+++ mono-3.2.8/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/ServerRecordProtocol.cs 2015-03-06 15:01:29.810597612 +0000 | |
@@ -33,6 +33,8 @@ | |
{ | |
internal class ServerRecordProtocol : RecordProtocol | |
{ | |
+ TlsClientCertificate cert; | |
+ | |
#region Constructors | |
public ServerRecordProtocol( | |
@@ -93,30 +95,45 @@ | |
private HandshakeMessage createClientHandshakeMessage( | |
HandshakeType type, byte[] buffer) | |
{ | |
+ var last = context.LastHandshakeMsg; | |
switch (type) | |
{ | |
case HandshakeType.ClientHello: | |
return new TlsClientHello(this.context, buffer); | |
case HandshakeType.Certificate: | |
- return new TlsClientCertificate(this.context, buffer); | |
+ if (last != HandshakeType.ClientHello) | |
+ break; | |
+ cert = new TlsClientCertificate(this.context, buffer); | |
+ return cert; | |
case HandshakeType.ClientKeyExchange: | |
- return new TlsClientKeyExchange(this.context, buffer); | |
+ if (last == HandshakeType.ClientHello || last == HandshakeType.Certificate) | |
+ return new TlsClientKeyExchange(this.context, buffer); | |
+ break; | |
case HandshakeType.CertificateVerify: | |
- return new TlsClientCertificateVerify(this.context, buffer); | |
+ if (last == HandshakeType.ClientKeyExchange && cert != null) | |
+ return new TlsClientCertificateVerify(this.context, buffer); | |
+ break; | |
case HandshakeType.Finished: | |
- return new TlsClientFinished(this.context, buffer); | |
- | |
+ // Certificates are optional, but if provided, they should send a CertificateVerify | |
+ bool check = (cert == null) ? (last == HandshakeType.ClientKeyExchange) : (last == HandshakeType.CertificateVerify); | |
+ // ChangeCipherSpecDone is not an handshake message (it's a content type) but still needs to be happens before finished | |
+ if (check && context.ChangeCipherSpecDone) { | |
+ context.ChangeCipherSpecDone = false; | |
+ return new TlsClientFinished(this.context, buffer); | |
+ } | |
+ break; | |
+ | |
default: | |
- throw new TlsException( | |
- AlertDescription.UnexpectedMessage, | |
- String.Format(CultureInfo.CurrentUICulture, | |
- "Unknown server handshake message received ({0})", | |
- type.ToString())); | |
+ throw new TlsException(AlertDescription.UnexpectedMessage, String.Format(CultureInfo.CurrentUICulture, | |
+ "Unknown server handshake message received ({0})", | |
+ type.ToString())); | |
+ break; | |
} | |
+ throw new TlsException (AlertDescription.HandshakeFailiure, String.Format ("Protocol error, unexpected protocol transition from {0} to {1}", last, type)); | |
} | |
private HandshakeMessage createServerHandshakeMessage( |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment