Imported Upstream version 6.8.0.73

Former-commit-id: d18deab1b47cfd3ad8cba82b3f37d00eec2170af
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2019-12-10 18:00:56 +00:00
parent bceda29824
commit 73ee7591e8
1043 changed files with 16271 additions and 22080 deletions

View File

@ -604,6 +604,7 @@ public class Tests : TestsBase, ITest2
if_property_stepping();
fixed_size_array();
test_new_exception_filter();
test_async_debug_generics();
return 3;
}
@ -903,6 +904,17 @@ public class Tests : TestsBase, ITest2
}
}
[MethodImplAttribute (MethodImplOptions.NoInlining)]
public static void test_async_debug_generics () {
ExecuteAsync_Broken<object>().Wait ();
}
async static Task<T> ExecuteAsync_Broken<T>()
{
await Task.Delay(2);
return default;
}
[MethodImplAttribute (MethodImplOptions.NoInlining)]
public static void inspect_enumerator_in_generic_struct() {
TestEnumeratorInsideGenericStruct<String, String> generic_struct = new TestEnumeratorInsideGenericStruct<String, String>(new KeyValuePair<string, string>("0", "f1"));

View File

@ -1 +1 @@
2bccbb137b170a01de42625d65883e868c508913
52da50a45dbfc7510ab393f4a443ee0caae46b7b

View File

@ -139,6 +139,7 @@ namespace Mono.Attach
else {
writer.Write ((sbyte)PrimitiveType.PRIM_TYPE_STRING);
writer.Write (s);
writer.Write ((byte)0);
}
}

View File

@ -43,33 +43,16 @@ namespace Mono.Messaging.RabbitMQ {
public class RabbitMQMessagingProvider : IMessagingProvider {
private int txCounter = 0;
private readonly uint localIp;
private readonly Guid localId;
private readonly MessagingContextPool contextPool;
public RabbitMQMessagingProvider ()
{
localIp = GetLocalIP ();
localId = Guid.NewGuid ();
contextPool = new MessagingContextPool (new MessageFactory (this),
CreateConnection);
}
private static uint GetLocalIP ()
{
String strHostName = Dns.GetHostName ();
IPHostEntry ipEntry = Dns.GetHostByName (strHostName);
foreach (IPAddress ip in ipEntry.AddressList) {
if (AddressFamily.InterNetwork == ip.AddressFamily) {
byte[] addr = ip.GetAddressBytes ();
uint localIP = 0;
for (int i = 0; i < 4 && i < addr.Length; i++) {
localIP += (uint) (addr[i] << 8 * (3 - i));
}
return localIP;
}
}
return 0;
}
public IMessage CreateMessage ()
{
return new MessageBase ();
@ -78,7 +61,7 @@ namespace Mono.Messaging.RabbitMQ {
public IMessageQueueTransaction CreateMessageQueueTransaction ()
{
Interlocked.Increment (ref txCounter);
string txId = localIp.ToString () + txCounter.ToString ();
string txId = localId.ToString () + "_" + txCounter.ToString ();
return new RabbitMQMessageQueueTransaction (txId, contextPool);
}

View File

@ -9,6 +9,7 @@ Mono.Unix/UnixPathTest.cs
Mono.Unix/UnixSignalTest.cs
Mono.Unix/UnixUserTest.cs
Mono.Unix.Android/TestHelper.cs
Mono.Unix.Native/OFDLockTest.cs
Mono.Unix.Native/RealTimeSignumTests.cs
Mono.Unix.Native/SocketTest.cs
Mono.Unix.Native/StdlibTest.cs

View File

@ -1 +1 @@
6cc67dda4b894bb3ef0dffdc49ae8e816665c012
c9eb750d22227382cc4989053d328c0e7fc0bc79

View File

@ -0,0 +1,133 @@
//
// Tests for FcntlCommand.F_OFD_{GETLK,SETLK,SETLKW}
//
// Authors:
// Steffen Kiess (kiess@ki4.de)
//
// Copyright (C) 2019 Steffen Kiess
//
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using Mono.Unix;
using Mono.Unix.Native;
using NUnit.Framework;
namespace MonoTests.Mono.Unix.Native
{
[TestFixture, Category ("NotDotNet"), Category ("NotOnWindows"), Category ("NotOnMac")]
public class OFDLockTest {
string TempFolder;
[SetUp]
public void SetUp ()
{
TempFolder = Path.Combine (Path.GetTempPath (), this.GetType ().FullName);
if (Directory.Exists (TempFolder))
Directory.Delete (TempFolder, true);
Directory.CreateDirectory (TempFolder);
}
[TearDown]
public void TearDown()
{
if (Directory.Exists (TempFolder))
Directory.Delete (TempFolder, true);
}
[Test]
public void TestOFDLock ()
{
int fd1 = Syscall.open (TempFolder + "/testfile", OpenFlags.O_RDWR | OpenFlags.O_CREAT | OpenFlags.O_EXCL, FilePermissions.DEFFILEMODE);
if (fd1 < 0)
UnixMarshal.ThrowExceptionForLastError ();
int fd2 = Syscall.open (TempFolder + "/testfile", OpenFlags.O_RDWR);
if (fd2 < 0)
UnixMarshal.ThrowExceptionForLastError ();
int fd3 = Syscall.open (TempFolder + "/testfile", OpenFlags.O_RDWR);
if (fd3 < 0)
UnixMarshal.ThrowExceptionForLastError ();
// Get read lock for first 100 bytes on fd1
var flock1 = new Flock {
l_type = LockType.F_RDLCK,
l_whence = SeekFlags.SEEK_SET,
l_start = 0,
l_len = 100,
};
if (Syscall.fcntl (fd1, FcntlCommand.F_OFD_SETLKW, ref flock1) < 0) {
// Old kernels and non-linux systems should return EINVAL
if (Stdlib.GetLastError () == Errno.EINVAL)
Assert.Ignore ("F_OFD_SETLKW does not seem to be supported.");
UnixMarshal.ThrowExceptionForLastError ();
}
// Get read lock for first 100 bytes on fd2
var flock2 = new Flock {
l_type = LockType.F_RDLCK,
l_whence = SeekFlags.SEEK_SET,
l_start = 0,
l_len = 100,
};
if (Syscall.fcntl (fd2, FcntlCommand.F_OFD_SETLK, ref flock2) < 0)
UnixMarshal.ThrowExceptionForLastError ();
// Get write lock for remaining bytes on fd1
var flock3 = new Flock {
l_type = LockType.F_WRLCK,
l_whence = SeekFlags.SEEK_SET,
l_start = 100,
l_len = 0,
};
if (Syscall.fcntl (fd1, FcntlCommand.F_OFD_SETLK, ref flock3) < 0)
UnixMarshal.ThrowExceptionForLastError ();
// Close fd3, should not release lock
if (Syscall.close (fd3) < 0)
UnixMarshal.ThrowExceptionForLastError ();
// Get lock status for byte 150 from fd2
var flock4 = new Flock {
l_type = LockType.F_RDLCK,
l_whence = SeekFlags.SEEK_SET,
l_start = 150,
l_len = 1,
};
if (Syscall.fcntl (fd2, FcntlCommand.F_OFD_GETLK, ref flock4) < 0)
UnixMarshal.ThrowExceptionForLastError ();
// There should be a conflicting write lock
Assert.AreEqual (LockType.F_WRLCK, flock4.l_type);
// Get write byte 0 on fd1, should fail with EAGAIN
var flock5 = new Flock {
l_type = LockType.F_WRLCK,
l_whence = SeekFlags.SEEK_SET,
l_start = 0,
l_len = 1,
};
var res = Syscall.fcntl (fd1, FcntlCommand.F_OFD_SETLK, ref flock5);
Assert.AreEqual (-1, res);
Assert.AreEqual (Errno.EAGAIN, Stdlib.GetLastError ());
if (Syscall.close (fd1) < 0)
UnixMarshal.ThrowExceptionForLastError ();
if (Syscall.close (fd2) < 0)
UnixMarshal.ThrowExceptionForLastError ();
}
}
}
// vim: noexpandtab
// Local Variables:
// tab-width: 4
// c-basic-offset: 4
// indent-tabs-mode: t
// End:

View File

@ -172,6 +172,7 @@ namespace Mono.Profiler.Log {
Debugger = 13,
Handle = 14,
Ephemeron = 15,
Toggleref = 16,
}
// mono/profiler/log.h : MonoProfilerMonitorEvent

View File

@ -96,14 +96,6 @@ namespace Mono.Security.Interface
ValidationResult ValidateCertificate (string targetHost, bool serverMode, X509CertificateCollection certificates);
}
internal interface ICertificateValidator2 : ICertificateValidator
{
/*
* Internal use only.
*/
ValidationResult ValidateCertificate (string targetHost, bool serverMode, X509Certificate leaf, X509Chain chain);
}
public static class CertificateValidationHelper
{
const string SecurityLibrary = "/System/Library/Frameworks/Security.framework/Security";

View File

@ -42,59 +42,11 @@ namespace Mono.Security.Interface
get;
}
void AuthenticateAsClient (string targetHost);
void AuthenticateAsClient (string targetHost, X509CertificateCollection clientCertificates, bool checkCertificateRevocation);
void AuthenticateAsClient (string targetHost, X509CertificateCollection clientCertificates, SSA.SslProtocols enabledSslProtocols, bool checkCertificateRevocation);
IAsyncResult BeginAuthenticateAsClient (string targetHost, AsyncCallback asyncCallback, object asyncState);
IAsyncResult BeginAuthenticateAsClient (string targetHost, X509CertificateCollection clientCertificates, bool checkCertificateRevocation, AsyncCallback asyncCallback, object asyncState);
IAsyncResult BeginAuthenticateAsClient (string targetHost, X509CertificateCollection clientCertificates, SSA.SslProtocols enabledSslProtocols, bool checkCertificateRevocation, AsyncCallback asyncCallback, object asyncState);
void EndAuthenticateAsClient (IAsyncResult asyncResult);
void AuthenticateAsServer (X509Certificate serverCertificate);
void AuthenticateAsServer (X509Certificate serverCertificate, bool clientCertificateRequired, bool checkCertificateRevocation);
void AuthenticateAsServer (X509Certificate serverCertificate, bool clientCertificateRequired, SSA.SslProtocols enabledSslProtocols, bool checkCertificateRevocation);
IAsyncResult BeginAuthenticateAsServer (X509Certificate serverCertificate, AsyncCallback asyncCallback, object asyncState);
IAsyncResult BeginAuthenticateAsServer (X509Certificate serverCertificate, bool clientCertificateRequired, bool checkCertificateRevocation, AsyncCallback asyncCallback, object asyncState);
IAsyncResult BeginAuthenticateAsServer (X509Certificate serverCertificate, bool clientCertificateRequired, SSA.SslProtocols enabledSslProtocols, bool checkCertificateRevocation, AsyncCallback asyncCallback, object asyncState);
void EndAuthenticateAsServer (IAsyncResult asyncResult);
Task AuthenticateAsClientAsync (string targetHost);
Task AuthenticateAsClientAsync (string targetHost, X509CertificateCollection clientCertificates, bool checkCertificateRevocation);
Task AuthenticateAsClientAsync (string targetHost, X509CertificateCollection clientCertificates, SSA.SslProtocols enabledSslProtocols, bool checkCertificateRevocation);
Task AuthenticateAsServerAsync (X509Certificate serverCertificate);
Task AuthenticateAsServerAsync (X509Certificate serverCertificate, bool clientCertificateRequired, bool checkCertificateRevocation);
Task AuthenticateAsServerAsync (X509Certificate serverCertificate, bool clientCertificateRequired, SSA.SslProtocols enabledSslProtocols, bool checkCertificateRevocation);
int Read (byte[] buffer, int offset, int count);
void Write (byte[] buffer);
void Write (byte[] buffer, int offset, int count);
IAsyncResult BeginRead (byte[] buffer, int offset, int count, AsyncCallback asyncCallback, object asyncState);
int EndRead (IAsyncResult asyncResult);
IAsyncResult BeginWrite (byte[] buffer, int offset, int count, AsyncCallback asyncCallback, object asyncState);
void EndWrite (IAsyncResult asyncResult);
Task<int> ReadAsync (byte[] buffer, int offset, int count, CancellationToken cancellationToken);
Task WriteAsync (byte[] buffer, int offset, int count, CancellationToken cancellationToken);
@ -215,12 +167,5 @@ namespace Mono.Security.Interface
Task RenegotiateAsync (CancellationToken cancellationToken);
}
interface IMonoSslStream2 : IMonoSslStream
{
Task AuthenticateAsClientAsync (IMonoSslClientAuthenticationOptions sslClientAuthenticationOptions, CancellationToken cancellationToken);
Task AuthenticateAsServerAsync (IMonoSslServerAuthenticationOptions sslServerAuthenticationOptions, CancellationToken cancellationToken);
}
}

View File

@ -121,10 +121,6 @@ namespace Mono.Security.Interface
Stream innerStream, bool leaveInnerStreamOpen,
MonoTlsSettings settings = null);
internal abstract IMonoSslStream CreateSslStreamInternal (
SslStream sslStream, Stream innerStream, bool leaveInnerStreamOpen,
MonoTlsSettings settings);
#endregion
#region Native Certificate Implementation
@ -133,34 +129,6 @@ namespace Mono.Security.Interface
get { return false; }
}
internal virtual X509Certificate2Impl GetNativeCertificate (
byte[] data, string password, X509KeyStorageFlags flags)
{
throw new InvalidOperationException ();
}
internal virtual X509Certificate2Impl GetNativeCertificate (
X509Certificate certificate)
{
throw new InvalidOperationException ();
}
#endregion
#region Certificate Validation
/*
* If @serverMode is true, then we're a server and want to validate a certificate
* that we received from a client.
*
* On OS X and Mobile, the @chain will be initialized with the @certificates, but not actually built.
*
* Returns `true` if certificate validation has been performed and `false` to invoke the
* default system validator.
*/
internal abstract bool ValidateCertificate (
ICertificateValidator2 validator, string targetHost, bool serverMode,
X509CertificateCollection certificates, bool wantsChain, ref X509Chain chain,
ref MonoSslPolicyErrors errors, ref int status11);
#endregion
#region Misc

View File

@ -183,9 +183,10 @@ namespace Mono.Security.Interface
* - 1: everything up until May 2018
* - 2: the new ServicePointScheduler changes have landed
* - 3: full support for Client Certificates
* - 4: Legacy TLS Removal
*
*/
internal const int InternalVersion = 3;
internal const int InternalVersion = 4;
#endregion
}

View File

@ -1,149 +0,0 @@
// Transport Security Layer (TLS)
// Copyright (c) 2003-2004 Carlos Guzman Alvarez
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Security.Cryptography.X509Certificates;
using Mono.Security.Protocol.Tls;
namespace Mono.Security.Protocol.Tls.Handshake.Client
{
internal class TlsClientCertificate : HandshakeMessage
{
private bool clientCertSelected;
private X509Certificate clientCert;
#region Constructors
public TlsClientCertificate(Context context)
: base(context, HandshakeType.Certificate)
{
}
#endregion
#region Properties
public X509Certificate ClientCertificate {
get {
if (!clientCertSelected)
{
GetClientCertificate ();
clientCertSelected = true;
}
return clientCert;
}
}
#endregion
#region Methods
public override void Update()
{
base.Update();
this.Reset();
}
#endregion
#region Protected Methods
private void GetClientCertificate ()
{
// TODO: Client certificate selection is unfinished
ClientContext context = (ClientContext)this.Context;
// note: the server may ask for mutual authentication
// but may not require it (i.e. it can be optional).
if (context.ClientSettings.Certificates != null &&
context.ClientSettings.Certificates.Count > 0)
{
clientCert = context.SslStream.RaiseClientCertificateSelection(
this.Context.ClientSettings.Certificates,
new X509Certificate(this.Context.ServerSettings.Certificates[0].RawData),
this.Context.ClientSettings.TargetHost,
null);
// Note: the application code can raise it's
// own exception to stop the connection too.
}
// Update the selected client certificate
context.ClientSettings.ClientCertificate = clientCert;
}
private void SendCertificates ()
{
TlsStream chain = new TlsStream ();
X509Certificate currentCert = this.ClientCertificate;
while (currentCert != null) {
byte[] rawCert = currentCert.GetRawCertData ();
chain.WriteInt24 (rawCert.Length);
chain.Write(rawCert);
currentCert = FindParentCertificate (currentCert);
}
this.WriteInt24 ((int)chain.Length);
this.Write (chain.ToArray ());
}
protected override void ProcessAsSsl3()
{
if (this.ClientCertificate != null) {
SendCertificates ();
} else {
// an Alert warning for NoCertificate (41)
// should be sent from here - but that would
// break the current message handling
}
}
protected override void ProcessAsTls1()
{
if (this.ClientCertificate != null) {
SendCertificates ();
} else {
// return message with empty certificate (see 7.4.6 in RFC2246)
this.WriteInt24 (0);
}
}
private X509Certificate FindParentCertificate (X509Certificate cert)
{
#pragma warning disable 618
// This certificate is the root certificate
if (cert.GetName () == cert.GetIssuerName ())
return null;
foreach (X509Certificate certificate in this.Context.ClientSettings.Certificates) {
if (certificate.GetName () == cert.GetIssuerName ())
return certificate;
}
return null;
#pragma warning restore 618
}
#endregion
}
}

View File

@ -1,220 +0,0 @@
// Transport Security Layer (TLS)
// Copyright (c) 2003-2004 Carlos Guzman Alvarez
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Security.Cryptography.X509Certificates;
using System.Security.Cryptography;
using Mono.Security.Cryptography;
namespace Mono.Security.Protocol.Tls.Handshake.Client
{
internal class TlsClientCertificateVerify : HandshakeMessage
{
#region Constructors
public TlsClientCertificateVerify(Context context)
: base(context, HandshakeType.CertificateVerify)
{
}
#endregion
#region Methods
public override void Update()
{
base.Update();
this.Reset();
}
#endregion
#region Protected Methods
protected override void ProcessAsSsl3()
{
AsymmetricAlgorithm privKey = null;
ClientContext context = (ClientContext)this.Context;
privKey = context.SslStream.RaisePrivateKeySelection(
context.ClientSettings.ClientCertificate,
context.ClientSettings.TargetHost);
if (privKey == null)
{
throw new TlsException(AlertDescription.UserCancelled, "Client certificate Private Key unavailable.");
}
else
{
SslHandshakeHash hash = new SslHandshakeHash(context.MasterSecret);
hash.TransformFinalBlock(
context.HandshakeMessages.ToArray(),
0,
(int)context.HandshakeMessages.Length);
// CreateSignature uses ((RSA)privKey).DecryptValue which is not implemented
// in RSACryptoServiceProvider. Other implementations likely implement DecryptValue
// so we will try the CreateSignature method.
byte[] signature = null;
if (!(privKey is RSACryptoServiceProvider))
{
try
{
signature = hash.CreateSignature((RSA)privKey);
}
catch (NotImplementedException)
{ }
}
// If DecryptValue is not implemented, then try to export the private
// key and let the RSAManaged class do the DecryptValue
if (signature == null)
{
// RSAManaged of the selected ClientCertificate
// (at this moment the first one)
RSA rsa = this.getClientCertRSA((RSA)privKey);
// Write message
signature = hash.CreateSignature(rsa);
}
this.Write((short)signature.Length);
this.Write(signature, 0, signature.Length);
}
}
protected override void ProcessAsTls1()
{
AsymmetricAlgorithm privKey = null;
ClientContext context = (ClientContext)this.Context;
privKey = context.SslStream.RaisePrivateKeySelection(
context.ClientSettings.ClientCertificate,
context.ClientSettings.TargetHost);
if (privKey == null)
{
throw new TlsException(AlertDescription.UserCancelled, "Client certificate Private Key unavailable.");
}
else
{
// Compute handshake messages hash
MD5SHA1 hash = new MD5SHA1();
hash.ComputeHash(
context.HandshakeMessages.ToArray(),
0,
(int)context.HandshakeMessages.Length);
// CreateSignature uses ((RSA)privKey).DecryptValue which is not implemented
// in RSACryptoServiceProvider. Other implementations likely implement DecryptValue
// so we will try the CreateSignature method.
byte[] signature = null;
if (!(privKey is RSACryptoServiceProvider))
{
try
{
signature = hash.CreateSignature((RSA)privKey);
}
catch (NotImplementedException)
{ }
}
// If DecryptValue is not implemented, then try to export the private
// key and let the RSAManaged class do the DecryptValue
if (signature == null)
{
// RSAManaged of the selected ClientCertificate
// (at this moment the first one)
RSA rsa = this.getClientCertRSA((RSA)privKey);
// Write message
signature = hash.CreateSignature(rsa);
}
this.Write((short)signature.Length);
this.Write(signature, 0, signature.Length);
}
}
#endregion
#region Private methods
private RSA getClientCertRSA(RSA privKey)
{
RSAParameters rsaParams = new RSAParameters();
RSAParameters privateParams = privKey.ExportParameters(true);
// for RSA m_publickey contains 2 ASN.1 integers
// the modulus and the public exponent
ASN1 pubkey = new ASN1 (this.Context.ClientSettings.Certificates[0].GetPublicKey());
ASN1 modulus = pubkey [0];
if ((modulus == null) || (modulus.Tag != 0x02))
{
return null;
}
ASN1 exponent = pubkey [1];
if (exponent.Tag != 0x02)
{
return null;
}
rsaParams.Modulus = this.getUnsignedBigInteger(modulus.Value);
rsaParams.Exponent = exponent.Value;
// Set private key parameters
rsaParams.D = privateParams.D;
rsaParams.DP = privateParams.DP;
rsaParams.DQ = privateParams.DQ;
rsaParams.InverseQ = privateParams.InverseQ;
rsaParams.P = privateParams.P;
rsaParams.Q = privateParams.Q;
// BUG: MS BCL 1.0 can't import a key which
// isn't the same size as the one present in
// the container.
int keySize = (rsaParams.Modulus.Length << 3);
RSAManaged rsa = new RSAManaged(keySize);
rsa.ImportParameters (rsaParams);
return (RSA)rsa;
}
private byte[] getUnsignedBigInteger(byte[] integer)
{
if (integer [0] == 0x00)
{
// this first byte is added so we're sure it's an unsigned integer
// however we can't feed it into RSAParameters or DSAParameters
int length = integer.Length - 1;
byte[] uinteger = new byte [length];
Buffer.BlockCopy (integer, 1, uinteger, 0, length);
return uinteger;
}
else
{
return integer;
}
}
#endregion
}
}

View File

@ -1,87 +0,0 @@
// Transport Security Layer (TLS)
// Copyright (c) 2003-2004 Carlos Guzman Alvarez
// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Security.Cryptography;
using Mono.Security.Cryptography;
namespace Mono.Security.Protocol.Tls.Handshake.Client
{
internal class TlsClientFinished : HandshakeMessage
{
#region Constructors
public TlsClientFinished(Context context)
: base(context, HandshakeType.Finished)
{
}
#endregion
#region Methods
public override void Update()
{
base.Update();
this.Reset();
}
#endregion
#region Protected Methods
static private byte[] Ssl3Marker = new byte [4] { 0x43, 0x4c, 0x4e, 0x54 };
protected override void ProcessAsSsl3()
{
// Compute handshake messages hashes
HashAlgorithm hash = new SslHandshakeHash(this.Context.MasterSecret);
byte[] data = this.Context.HandshakeMessages.ToArray ();
hash.TransformBlock (data, 0, data.Length, data, 0);
hash.TransformBlock (Ssl3Marker, 0, Ssl3Marker.Length, Ssl3Marker, 0);
// hack to avoid memory allocation
hash.TransformFinalBlock (CipherSuite.EmptyArray, 0, 0);
this.Write (hash.Hash);
}
protected override void ProcessAsTls1()
{
// Compute handshake messages hash
HashAlgorithm hash = new MD5SHA1();
// note: we could call HashAlgorithm.ComputeHash(Stream) but that would allocate (on Mono)
// a 4096 bytes buffer to process the hash - which is bigger than HandshakeMessages
byte[] data = this.Context.HandshakeMessages.ToArray ();
byte[] digest = hash.ComputeHash (data, 0, data.Length);
// Write message
Write(this.Context.Write.Cipher.PRF(this.Context.MasterSecret, "client finished", digest, 12));
}
#endregion
}
}

View File

@ -1,139 +0,0 @@
// Transport Security Layer (TLS)
// Copyright (c) 2003-2004 Carlos Guzman Alvarez
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Net;
using System.Security.Cryptography;
namespace Mono.Security.Protocol.Tls.Handshake.Client
{
internal class TlsClientHello : HandshakeMessage
{
#region Fields
private byte[] random;
#endregion
#region Constructors
public TlsClientHello(Context context)
: base(context, HandshakeType.ClientHello)
{
}
#endregion
#region Methods
public override void Update()
{
ClientContext context = (ClientContext)this.Context;
base.Update();
context.ClientRandom = random;
context.ClientHelloProtocol = this.Context.Protocol;
random = null;
}
#endregion
#region Protected Methods
protected override void ProcessAsSsl3()
{
// Client Version
this.Write(this.Context.Protocol);
// Random bytes - Unix time + Radom bytes [28]
TlsStream clientRandom = new TlsStream();
clientRandom.Write(this.Context.GetUnixTime());
clientRandom.Write(this.Context.GetSecureRandomBytes(28));
this.random = clientRandom.ToArray();
clientRandom.Reset();
this.Write(this.random);
// Session id
// Check if we have a cache session we could reuse
this.Context.SessionId = ClientSessionCache.FromHost (this.Context.ClientSettings.TargetHost);
if (this.Context.SessionId != null)
{
this.Write((byte)this.Context.SessionId.Length);
if (this.Context.SessionId.Length > 0)
{
this.Write(this.Context.SessionId);
}
}
else
{
this.Write((byte)0);
}
// Write length of Cipher suites
this.Write((short)(this.Context.SupportedCiphers.Count*2));
// Write Supported Cipher suites
for (int i = 0; i < this.Context.SupportedCiphers.Count; i++)
{
this.Write((short)this.Context.SupportedCiphers[i].Code);
}
// Compression methods length
this.Write((byte)1);
// Compression methods ( 0 = none )
this.Write((byte)this.Context.CompressionMethod);
}
protected override void ProcessAsTls1()
{
ProcessAsSsl3 ();
// If applicable add the "server_name" extension to the hello message
// http://www.ietf.org/rfc/rfc3546.txt
string host = Context.ClientSettings.TargetHost;
// Our TargetHost might be an address (not a host *name*) - see bug #8553
// RFC3546 -> Literal IPv4 and IPv6 addresses are not permitted in "HostName".
IPAddress addr;
if (IPAddress.TryParse (host, out addr))
return;
TlsStream extensions = new TlsStream ();
byte[] server_name = System.Text.Encoding.UTF8.GetBytes (host);
extensions.Write ((short) 0x0000); // ExtensionType: server_name (0)
extensions.Write ((short) (server_name.Length + 5)); // ServerNameList (length)
extensions.Write ((short) (server_name.Length + 3)); // ServerName (length)
extensions.Write ((byte) 0x00); // NameType: host_name (0)
extensions.Write ((short) server_name.Length); // HostName (length)
extensions.Write (server_name); // HostName (UTF8)
this.Write ((short) extensions.Length);
this.Write (extensions.ToArray ());
}
#endregion
}
}

View File

@ -1,98 +0,0 @@
// Transport Security Layer (TLS)
// Copyright (c) 2003-2004 Carlos Guzman Alvarez
// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Security.Cryptography;
using Mono.Security.Cryptography;
namespace Mono.Security.Protocol.Tls.Handshake.Client
{
internal class TlsClientKeyExchange : HandshakeMessage
{
#region Constructors
public TlsClientKeyExchange (Context context) :
base(context, HandshakeType.ClientKeyExchange)
{
}
#endregion
#region Protected Methods
protected override void ProcessAsSsl3()
{
// a large chunk of code is common to both SSL3 and TLS1
// SSL3 doesn't send the length of the buffer
ProcessCommon (false);
}
protected override void ProcessAsTls1()
{
// a large chunk of code is common to both SSL3 and TLS1
// TLS1 does send the length of the buffer
ProcessCommon (true);
}
public void ProcessCommon (bool sendLength)
{
// Compute pre master secret
byte[] preMasterSecret = this.Context.Negotiating.Cipher.CreatePremasterSecret ();
// Create a new RSA key
RSA rsa = null;
if (this.Context.ServerSettings.ServerKeyExchange)
{
// this is the case for "exportable" ciphers
rsa = new RSAManaged ();
rsa.ImportParameters (this.Context.ServerSettings.RsaParameters);
}
else
{
rsa = this.Context.ServerSettings.CertificateRSA;
}
// Encrypt premaster_sercret
RSAPKCS1KeyExchangeFormatter formatter = new RSAPKCS1KeyExchangeFormatter (rsa);
// Write the preMasterSecret encrypted
byte[] buffer = formatter.CreateKeyExchange (preMasterSecret);
if (sendLength)
this.Write ((short) buffer.Length);
this.Write (buffer);
// Create master secret
this.Context.Negotiating.Cipher.ComputeMasterSecret (preMasterSecret);
// Create keys
this.Context.Negotiating.Cipher.ComputeKeys ();
// Clear resources
rsa.Clear ();
}
#endregion
}
}

View File

@ -1,450 +0,0 @@
// Transport Security Layer (TLS)
// Copyright (c) 2003-2004 Carlos Guzman Alvarez
// Copyright (C) 2004, 2006-2010 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Net;
using System.Collections;
using System.Globalization;
using System.Text.RegularExpressions;
using System.Security.Cryptography;
using X509Cert = System.Security.Cryptography.X509Certificates;
using Mono.Security.X509;
using Mono.Security.X509.Extensions;
using Mono.Security.Interface;
namespace Mono.Security.Protocol.Tls.Handshake.Client
{
internal class TlsServerCertificate : HandshakeMessage
{
#region Fields
private X509CertificateCollection certificates;
#endregion
#region Constructors
public TlsServerCertificate(Context context, byte[] buffer)
: base(context, HandshakeType.Certificate, buffer)
{
}
#endregion
#region Methods
public override void Update()
{
base.Update();
this.Context.ServerSettings.Certificates = this.certificates;
this.Context.ServerSettings.UpdateCertificateRSA();
}
#endregion
#region Protected Methods
protected override void ProcessAsSsl3()
{
this.ProcessAsTls1();
}
protected override void ProcessAsTls1()
{
this.certificates = new X509CertificateCollection();
int readed = 0;
int length = this.ReadInt24();
while (readed < length)
{
// Read certificate length
int certLength = ReadInt24();
// Increment readed
readed += 3;
if (certLength > 0)
{
// Read certificate data
byte[] buffer = this.ReadBytes(certLength);
// Create a new X509 Certificate
X509Certificate certificate = new X509Certificate(buffer);
certificates.Add(certificate);
readed += certLength;
DebugHelper.WriteLine(
String.Format("Server Certificate {0}", certificates.Count),
buffer);
}
}
this.validateCertificates(certificates);
}
#endregion
#region Private Methods
// Note: this method only works for RSA certificates
// DH certificates requires some changes - does anyone use one ?
private bool checkCertificateUsage (X509Certificate cert)
{
ClientContext context = (ClientContext)this.Context;
// certificate extensions are required for this
// we "must" accept older certificates without proofs
if (cert.Version < 3)
return true;
KeyUsages ku = KeyUsages.none;
switch (context.Negotiating.Cipher.ExchangeAlgorithmType)
{
case ExchangeAlgorithmType.RsaSign:
ku = KeyUsages.digitalSignature;
break;
case ExchangeAlgorithmType.RsaKeyX:
ku = KeyUsages.keyEncipherment;
break;
case ExchangeAlgorithmType.DiffieHellman:
ku = KeyUsages.keyAgreement;
break;
case ExchangeAlgorithmType.Fortezza:
return false; // unsupported certificate type
}
KeyUsageExtension kux = null;
ExtendedKeyUsageExtension eku = null;
X509Extension xtn = cert.Extensions ["2.5.29.15"];
if (xtn != null)
kux = new KeyUsageExtension (xtn);
xtn = cert.Extensions ["2.5.29.37"];
if (xtn != null)
eku = new ExtendedKeyUsageExtension (xtn);
if ((kux != null) && (eku != null))
{
// RFC3280 states that when both KeyUsageExtension and
// ExtendedKeyUsageExtension are present then BOTH should
// be valid
if (!kux.Support (ku))
return false;
return (eku.KeyPurpose.Contains ("1.3.6.1.5.5.7.3.1") ||
eku.KeyPurpose.Contains ("2.16.840.1.113730.4.1"));
}
else if (kux != null)
{
return kux.Support (ku);
}
else if (eku != null)
{
// Server Authentication (1.3.6.1.5.5.7.3.1) or
// Netscape Server Gated Crypto (2.16.840.1.113730.4)
return (eku.KeyPurpose.Contains ("1.3.6.1.5.5.7.3.1") ||
eku.KeyPurpose.Contains ("2.16.840.1.113730.4.1"));
}
// last chance - try with older (deprecated) Netscape extensions
xtn = cert.Extensions ["2.16.840.1.113730.1.1"];
if (xtn != null)
{
NetscapeCertTypeExtension ct = new NetscapeCertTypeExtension (xtn);
return ct.Support (NetscapeCertTypeExtension.CertTypes.SslServer);
}
// if the CN=host (checked later) then we assume this is meant for SSL/TLS
// e.g. the new smtp.gmail.com certificate
return true;
}
private void validateCertificates(X509CertificateCollection certificates)
{
ClientContext context = (ClientContext)this.Context;
AlertDescription description = AlertDescription.BadCertificate;
#if INSIDE_SYSTEM
// This helps the linker to remove a lot of validation code that will never be used since
// System.dll will, for OSX and iOS, uses the operating system X.509 certificate validations
RemoteValidation (context, description);
#else
if (context.SslStream.HaveRemoteValidation2Callback)
RemoteValidation (context, description);
else
LocalValidation (context, description);
#endif
}
void RemoteValidation (ClientContext context, AlertDescription description)
{
ValidationResult res = context.SslStream.RaiseServerCertificateValidation2 (certificates);
if (res.Trusted)
return;
long error = res.ErrorCode;
switch (error) {
case 0x800B0101:
description = AlertDescription.CertificateExpired;
break;
case 0x800B010A:
description = AlertDescription.UnknownCA;
break;
case 0x800B0109:
description = AlertDescription.UnknownCA;
break;
default:
description = AlertDescription.CertificateUnknown;
break;
}
string err = String.Format ("Invalid certificate received from server. Error code: 0x{0:x}", error);
throw new TlsException (description, err);
}
void LocalValidation (ClientContext context, AlertDescription description)
{
// the leaf is the web server certificate
X509Certificate leaf = certificates [0];
X509Cert.X509Certificate cert = new X509Cert.X509Certificate (leaf.RawData);
ArrayList errors = new ArrayList();
// SSL specific check - not all certificates can be
// used to server-side SSL some rules applies after
// all ;-)
if (!checkCertificateUsage (leaf))
{
// WinError.h CERT_E_PURPOSE 0x800B0106
errors.Add ((int)-2146762490);
}
// SSL specific check - does the certificate match
// the host ?
if (!checkServerIdentity (leaf))
{
// WinError.h CERT_E_CN_NO_MATCH 0x800B010F
errors.Add ((int)-2146762481);
}
// Note: building and verifying a chain can take much time
// so we do it last (letting simple things fails first)
// Note: In TLS the certificates MUST be in order (and
// optionally include the root certificate) so we're not
// building the chain using LoadCertificate (it's faster)
// Note: IIS doesn't seem to send the whole certificate chain
// but only the server certificate :-( it's assuming that you
// already have this chain installed on your computer. duh!
// http://groups.google.ca/groups?q=IIS+server+certificate+chain&hl=en&lr=&ie=UTF-8&oe=UTF-8&selm=85058s%24avd%241%40nnrp1.deja.com&rnum=3
// we must remove the leaf certificate from the chain
X509CertificateCollection chain = new X509CertificateCollection (certificates);
chain.Remove (leaf);
X509Chain verify = new X509Chain (chain);
bool result = false;
try
{
result = verify.Build (leaf);
}
catch (Exception)
{
result = false;
}
if (!result)
{
switch (verify.Status)
{
case X509ChainStatusFlags.InvalidBasicConstraints:
// WinError.h TRUST_E_BASIC_CONSTRAINTS 0x80096019
errors.Add ((int)-2146869223);
break;
case X509ChainStatusFlags.NotSignatureValid:
// WinError.h TRUST_E_BAD_DIGEST 0x80096010
errors.Add ((int)-2146869232);
break;
case X509ChainStatusFlags.NotTimeNested:
// WinError.h CERT_E_VALIDITYPERIODNESTING 0x800B0102
errors.Add ((int)-2146762494);
break;
case X509ChainStatusFlags.NotTimeValid:
// WinError.h CERT_E_EXPIRED 0x800B0101
description = AlertDescription.CertificateExpired;
errors.Add ((int)-2146762495);
break;
case X509ChainStatusFlags.PartialChain:
// WinError.h CERT_E_CHAINING 0x800B010A
description = AlertDescription.UnknownCA;
errors.Add ((int)-2146762486);
break;
case X509ChainStatusFlags.UntrustedRoot:
// WinError.h CERT_E_UNTRUSTEDROOT 0x800B0109
description = AlertDescription.UnknownCA;
errors.Add ((int)-2146762487);
break;
default:
// unknown error
description = AlertDescription.CertificateUnknown;
errors.Add ((int)verify.Status);
break;
}
}
int[] certificateErrors = (int[])errors.ToArray(typeof(int));
if (!context.SslStream.RaiseServerCertificateValidation(
cert,
certificateErrors))
{
throw new TlsException(
description,
"Invalid certificate received from server.");
}
}
// RFC2818 - HTTP Over TLS, Section 3.1
// http://www.ietf.org/rfc/rfc2818.txt
//
// 1. if present MUST use subjectAltName dNSName as identity
// 1.1. if multiples entries a match of any one is acceptable
// 1.2. wildcard * is acceptable
// 2. URI may be an IP address -> subjectAltName.iPAddress
// 2.1. exact match is required
// 3. Use of the most specific Common Name (CN=) in the Subject
// 3.1 Existing practice but DEPRECATED
private bool checkServerIdentity (X509Certificate cert)
{
ClientContext context = (ClientContext)this.Context;
string targetHost = context.ClientSettings.TargetHost;
X509Extension ext = cert.Extensions ["2.5.29.17"];
// 1. subjectAltName
if (ext != null)
{
SubjectAltNameExtension subjectAltName = new SubjectAltNameExtension (ext);
// 1.1 - multiple dNSName
foreach (string dns in subjectAltName.DNSNames)
{
// 1.2 TODO - wildcard support
if (Match (targetHost, dns))
return true;
}
// 2. ipAddress
foreach (string ip in subjectAltName.IPAddresses)
{
// 2.1. Exact match required
if (ip == targetHost)
return true;
}
}
// 3. Common Name (CN=)
return checkDomainName (cert.SubjectName);
}
private bool checkDomainName(string subjectName)
{
ClientContext context = (ClientContext)this.Context;
string domainName = String.Empty;
Regex search = new Regex(@"CN\s*=\s*([^,]*)");
MatchCollection elements = search.Matches(subjectName);
if (elements.Count == 1)
{
if (elements[0].Success)
{
domainName = elements[0].Groups[1].Value.ToString();
}
}
return Match (context.ClientSettings.TargetHost, domainName);
}
// ensure the pattern is valid wrt to RFC2595 and RFC2818
// http://www.ietf.org/rfc/rfc2595.txt
// http://www.ietf.org/rfc/rfc2818.txt
static bool Match (string hostname, string pattern)
{
// check if this is a pattern
int index = pattern.IndexOf ('*');
if (index == -1) {
// not a pattern, do a direct case-insensitive comparison
return (String.Compare (hostname, pattern, true, CultureInfo.InvariantCulture) == 0);
}
// check pattern validity
// A "*" wildcard character MAY be used as the left-most name component in the certificate.
// unless this is the last char (valid)
if (index != pattern.Length - 1) {
// then the next char must be a dot .'.
if (pattern [index + 1] != '.')
return false;
}
// only one (A) wildcard is supported
int i2 = pattern.IndexOf ('*', index + 1);
if (i2 != -1)
return false;
// match the end of the pattern
string end = pattern.Substring (index + 1);
int length = hostname.Length - end.Length;
// no point to check a pattern that is longer than the hostname
if (length <= 0)
return false;
if (String.Compare (hostname, length, end, 0, end.Length, true, CultureInfo.InvariantCulture) != 0)
return false;
// special case, we start with the wildcard
if (index == 0) {
// ensure we hostname non-matched part (start) doesn't contain a dot
int i3 = hostname.IndexOf ('.');
return ((i3 == -1) || (i3 >= (hostname.Length - end.Length)));
}
// match the start of the pattern
string start = pattern.Substring (0, index);
return (String.Compare (hostname, 0, start, 0, start.Length, true, CultureInfo.InvariantCulture) == 0);
}
#endregion
}
}

View File

@ -1,111 +0,0 @@
// Transport Security Layer (TLS)
// Copyright (c) 2003-2004 Carlos Guzman Alvarez
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Text;
using Mono.Security;
namespace Mono.Security.Protocol.Tls.Handshake.Client
{
internal class TlsServerCertificateRequest : HandshakeMessage
{
#region Fields
private ClientCertificateType[] certificateTypes;
private string[] distinguisedNames;
#endregion
#region Constructors
public TlsServerCertificateRequest(Context context, byte[] buffer)
: base(context, HandshakeType.CertificateRequest, buffer)
{
}
#endregion
#region Methods
public override void Update()
{
base.Update();
this.Context.ServerSettings.CertificateTypes = this.certificateTypes;
this.Context.ServerSettings.DistinguisedNames = this.distinguisedNames;
this.Context.ServerSettings.CertificateRequest = true;
}
#endregion
#region Protected Methods
protected override void ProcessAsSsl3()
{
this.ProcessAsTls1();
}
protected override void ProcessAsTls1()
{
// Read requested certificate types
int typesCount = this.ReadByte();
this.certificateTypes = new ClientCertificateType[typesCount];
for (int i = 0; i < typesCount; i++)
{
this.certificateTypes[i] = (ClientCertificateType)this.ReadByte();
}
/*
* Read requested certificate authorities (Distinguised Names)
*
* Name ::= SEQUENCE OF RelativeDistinguishedName
*
* RelativeDistinguishedName ::= SET OF AttributeValueAssertion
*
* AttributeValueAssertion ::= SEQUENCE {
* attributeType OBJECT IDENTIFIER
* attributeValue ANY }
*/
if (this.ReadInt16() != 0)
{
ASN1 rdn = new ASN1(this.ReadBytes(this.ReadInt16()));
distinguisedNames = new string[rdn.Count];
for (int i = 0; i < rdn.Count; i++)
{
// element[0] = attributeType
// element[1] = attributeValue
ASN1 element = new ASN1(rdn[i].Value);
distinguisedNames[i] = Encoding.UTF8.GetString(element[1].Value);
}
}
}
#endregion
}
}

View File

@ -1,102 +0,0 @@
// Transport Security Layer (TLS)
// Copyright (c) 2003-2004 Carlos Guzman Alvarez
// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Security.Cryptography;
using Mono.Security.Cryptography;
namespace Mono.Security.Protocol.Tls.Handshake.Client
{
internal class TlsServerFinished : HandshakeMessage
{
#region Constructors
public TlsServerFinished(Context context, byte[] buffer)
: base(context, HandshakeType.Finished, buffer)
{
}
#endregion
#region Methods
public override void Update()
{
base.Update();
// Hahdshake is finished
this.Context.HandshakeState = HandshakeState.Finished;
}
#endregion
#region Protected Methods
static private byte[] Ssl3Marker = new byte [4] { 0x53, 0x52, 0x56, 0x52 };
protected override void ProcessAsSsl3()
{
// Compute handshake messages hashes
HashAlgorithm hash = new SslHandshakeHash(this.Context.MasterSecret);
byte[] data = this.Context.HandshakeMessages.ToArray ();
hash.TransformBlock (data, 0, data.Length, data, 0);
hash.TransformBlock (Ssl3Marker, 0, Ssl3Marker.Length, Ssl3Marker, 0);
// hack to avoid memory allocation
hash.TransformFinalBlock (CipherSuite.EmptyArray, 0, 0);
byte[] serverHash = this.ReadBytes((int)Length);
byte[] clientHash = hash.Hash;
// Check server prf against client prf
if (!Compare (clientHash, serverHash))
{
// TODO: Review that selected alert is correct
throw new TlsException(AlertDescription.InsuficientSecurity, "Invalid ServerFinished message received.");
}
}
protected override void ProcessAsTls1()
{
byte[] serverPRF = this.ReadBytes((int)Length);
HashAlgorithm hash = new MD5SHA1();
// note: we could call HashAlgorithm.ComputeHash(Stream) but that would allocate (on Mono)
// a 4096 bytes buffer to process the hash - which is bigger than HandshakeMessages
byte[] data = this.Context.HandshakeMessages.ToArray ();
byte[] digest = hash.ComputeHash (data, 0, data.Length);
byte[] clientPRF = this.Context.Current.Cipher.PRF(this.Context.MasterSecret, "server finished", digest, 12);
// Check server prf against client prf
if (!Compare (clientPRF, serverPRF))
{
throw new TlsException("Invalid ServerFinished message received.");
}
}
#endregion
}
}

Some files were not shown because too many files have changed in this diff Show More