xamarin-macios/tests/monotouch-test/Security/SecureTransportTest.cs

242 строки
10 KiB
C#
Исходник Обычный вид История

2016-05-26 16:06:52 +03:00
//
// SecureTransport Unit Tests
//
// Authors:
// Sebastien Pouliot <sebastien@xamarin.com>
//
// Copyright 2014 Xamarin Inc.
//
using System;
using System.Net.Sockets;
using System.Text;
using System.Threading;
#if XAMCORE_2_0
using Foundation;
using Security;
using ObjCRuntime;
#if MONOMAC
using AppKit;
#else
using UIKit;
#endif
2016-05-26 16:06:52 +03:00
#else
using MonoTouch.Foundation;
using MonoTouch.Security;
using MonoTouch.ObjCRuntime;
using MonoTouch.UIKit;
2016-05-26 16:06:52 +03:00
#endif
using NUnit.Framework;
#if XAMCORE_2_0
using RectangleF=CoreGraphics.CGRect;
using SizeF=CoreGraphics.CGSize;
using PointF=CoreGraphics.CGPoint;
#else
using nfloat=global::System.Single;
using nint=global::System.Int32;
using nuint=global::System.UInt32;
#endif
namespace MonoTouchFixtures.Security {
[TestFixture]
// we want the test to be available if we use the linker
[Preserve (AllMembers = true)]
public class SecureTransportTest {
const int errSecParam = -50;
const int errSecAllocate = -108;
[Test]
public void StreamDefaults ()
{
TestRuntime.AssertSystemVersion (PlatformName.MacOSX, 10, 8, throwIfOtherPlatform: false);
2016-05-26 16:06:52 +03:00
using (var ssl = new SslContext (SslProtocolSide.Client, SslConnectionType.Stream)) {
Assert.That (ssl.BufferedReadSize, Is.EqualTo ((nint) 0), "BufferedReadSize");
Assert.That (ssl.ClientCertificateState, Is.EqualTo (SslClientCertificateState.None), "ClientCertificateState");
Assert.Null (ssl.Connection, "Connection");
Assert.That (ssl.DatagramWriteSize, Is.EqualTo ((nint) 0), "DatagramWriteSize");
Assert.That (ssl.Handle, Is.Not.EqualTo (IntPtr.Zero), "Handle");
Assert.That (ssl.MaxDatagramRecordSize, Is.EqualTo ((nint) 0), "MaxDatagramRecordSize");
Assert.That (ssl.MaxProtocol, Is.EqualTo (SslProtocol.Tls_1_2), "MaxProtocol");
if (TestRuntime.CheckXcodeVersion (8, 0))
Assert.That (ssl.MinProtocol, Is.EqualTo (SslProtocol.Tls_1_0), "MinProtocol");
else
Assert.That (ssl.MinProtocol, Is.EqualTo (SslProtocol.Ssl_3_0), "MinProtocol");
2016-05-26 16:06:52 +03:00
Assert.That (ssl.NegotiatedCipher, Is.EqualTo (SslCipherSuite.SSL_NULL_WITH_NULL_NULL), "NegotiatedCipher");
Assert.That (ssl.NegotiatedProtocol, Is.EqualTo (SslProtocol.Unknown), "NegotiatedProtocol");
Assert.That (ssl.PeerDomainName, Is.Empty, "PeerDomainName");
ssl.PeerDomainName = "google.ca";
Assert.That (ssl.PeerDomainName, Is.EqualTo ("google.ca"), "PeerDomainName-2");
ssl.PeerDomainName = null;
Assert.That (ssl.PeerDomainName, Is.Empty, "PeerDomainName");
Assert.Null (ssl.PeerId, "PeerId");
ssl.PeerId = new byte [] { 0xff };
Assert.That (ssl.PeerId.Length, Is.EqualTo (1), "1a");
// note: SSLSetPeerID (see Apple open source code) does not accept a null/zero-length value
ssl.PeerId = new byte [0];
Assert.That ((int) ssl.GetLastStatus (), Is.EqualTo (errSecParam), "set_PeerId/empty");
Assert.That (ssl.PeerId.Length, Is.EqualTo (1), "1b");
ssl.PeerId = new byte [] { 0x01, 0x02 };
Assert.That (ssl.PeerId.Length, Is.EqualTo (2), "2");
Assert.Null (ssl.PeerTrust, "PeerTrust");
Assert.That (ssl.SessionState, Is.EqualTo (SslSessionState.Idle), "SessionState");
Assert.That ((int)ssl.SetDatagramHelloCookie (new byte [32]), Is.EqualTo (-50), "no cookie in stream");
// Assert.Null (ssl.GetDistinguishedNames<string> (), "GetDistinguishedNames");
if (TestRuntime.CheckXcodeVersion (9,0)) {
Assert.That (ssl.SetSessionTickets (false), Is.EqualTo (0), "SetSessionTickets");
Assert.That (ssl.SetError (SecStatusCode.Success), Is.EqualTo (0), "SetError");
Assert.Throws<ArgumentNullException> (() => ssl.SetOcspResponse (null), "SetOcspResponse/null");
using (var data = new NSData ())
Assert.That (ssl.SetOcspResponse (data), Is.EqualTo (0), "SetOcspResponse/empty");
Bump to use Xcode 10 beta 1 (#4179) * Bump to use Xcode 10 beta 1 * Update Versions.plist * Add a dependency on Xcode 9.4. * [msbuild] Fix build with Xcode 10 beta 1. (#4182) Many years ago (in Xcode 7 according to code comment) Developer/Platforms/iPhoneOS.platform/Developer/usr disappeared, and we coped by looking at Developer/usr instead (and also the subsequent code to locate the bin directory was based on the location of the usr directory). Developer/Platforms/iPhoneOS.platform/Developer/usr reappeared in Xcode 10 beta 1, but it seems useless (for one it doesn't contain a bin directory), so in order to try to keep things sane don't look for this directory in Xcode 10 and instead go directly for Developer/usr (which is what we've been using as the usr directory for years anyway). Fixes this problem when building apps with Xcode 10 beta 1: /Library/Frameworks/Mono.framework/External/xbuild/Xamarin/iOS/Xamarin.iOS.Common.targets(626,3): error : Could not locate SDK bin directory [/Users/rolf/Projects/TestApp/test-app.csproj] * [runtime] Build 32-bit mac executables using Xcode 9.4. * [mtouch] Work around broken tvOS headers in Xcode 10 beta 1. * [mtouch] Work around build problem with Apple's simd headers in Objective-C++ mode. * Use version-agnostic paths to sdk directories. * [tests][xtro] Add todo files (from unclassified) and adjust ignore files to avoid errors * [macos][security] Re-enable SSL[Get|Set]AlpnProtocols. Fixes #4001 (#4022) * [macos][security] Re-enable SSL[Get}Set]AlpnProtocols. Fixes #4001 This was fixed in macOS 10.13.4 https://github.com/xamarin/xamarin-macios/issues/4001 * [tests][monotouch-tests] Disable a few test cases (one crasher, other failures). Causes to be verified later * [xharness] Fix permission dialog suppression in Xcode 10. * [xharness] Ignore 32-bit macOS tests by default. * [tests] Execute mmp regression tests with Xcode 9.4 since many of them are 32-bit and needs porting to 64-bit. * [mmptest] Ignore 32-bit XM tests if we don't have a 32-bit-capable Xcode. * [registrar] Add workaround for broken headers in Xcode 10 beta 1 (radar 40824697). * [mtouch] Restrict another workaround for an Xcode 10 beta 1 bug to a specific Xcode version to remove it asap. * [tests] Fix some protocol changes (public or not) find by introspection tests * [tests][intro] Fix DefaultCtorAllowed failures * [Intents] Obsolete several Intents classes in watchOS. Several existing Intents classes have been marked as unavailable in watchOS in the headers in Xcode 10 beta 1, and corresponding tests are now failing. So obsolete the managed wrapper types, and fix tests accordingly. * Fix xtro wrt previous Ietents/intro changes * [tests] Minor adjustments to mtouch tests to work with Xcode 10. * [msbuild] Update tests to cope with additional files produced by the Core ML compiler. * [msbuild] Xcode 10 doesn't support building watchOS 1 apps, so show a clear error message explaining it. Also update tests accordingly. * [coreimage] Stub new filters and exclude ?removed? ones from tests * Update GameplayKit and SpriteKit NSSecureCoding _upgrade_ and fix other non-public cases (in tests) * [tests] Ignore some GameKit selectors that don't respond anymore (but seems to be available, at least in header files) * [tests] Fix intro 32bits testing for filters resutls * [msbuild] Slightly change error message to be better English.
2018-06-09 04:45:24 +03:00
#if MONOMAC
if (TestRuntime.CheckXcodeVersion (9,3)) {
#endif
int error;
var alpn = ssl.GetAlpnProtocols (out error);
Assert.That (alpn, Is.Empty, "alpn");
Assert.That (error, Is.EqualTo ((int) SecStatusCode.Param), "GetAlpnProtocols");
var protocols = new [] { "HTTP/1.1", "SPDY/1" };
Assert.That (ssl.SetAlpnProtocols (protocols), Is.EqualTo (0), "SetAlpnProtocols");
Bump to use Xcode 10 beta 1 (#4179) * Bump to use Xcode 10 beta 1 * Update Versions.plist * Add a dependency on Xcode 9.4. * [msbuild] Fix build with Xcode 10 beta 1. (#4182) Many years ago (in Xcode 7 according to code comment) Developer/Platforms/iPhoneOS.platform/Developer/usr disappeared, and we coped by looking at Developer/usr instead (and also the subsequent code to locate the bin directory was based on the location of the usr directory). Developer/Platforms/iPhoneOS.platform/Developer/usr reappeared in Xcode 10 beta 1, but it seems useless (for one it doesn't contain a bin directory), so in order to try to keep things sane don't look for this directory in Xcode 10 and instead go directly for Developer/usr (which is what we've been using as the usr directory for years anyway). Fixes this problem when building apps with Xcode 10 beta 1: /Library/Frameworks/Mono.framework/External/xbuild/Xamarin/iOS/Xamarin.iOS.Common.targets(626,3): error : Could not locate SDK bin directory [/Users/rolf/Projects/TestApp/test-app.csproj] * [runtime] Build 32-bit mac executables using Xcode 9.4. * [mtouch] Work around broken tvOS headers in Xcode 10 beta 1. * [mtouch] Work around build problem with Apple's simd headers in Objective-C++ mode. * Use version-agnostic paths to sdk directories. * [tests][xtro] Add todo files (from unclassified) and adjust ignore files to avoid errors * [macos][security] Re-enable SSL[Get|Set]AlpnProtocols. Fixes #4001 (#4022) * [macos][security] Re-enable SSL[Get}Set]AlpnProtocols. Fixes #4001 This was fixed in macOS 10.13.4 https://github.com/xamarin/xamarin-macios/issues/4001 * [tests][monotouch-tests] Disable a few test cases (one crasher, other failures). Causes to be verified later * [xharness] Fix permission dialog suppression in Xcode 10. * [xharness] Ignore 32-bit macOS tests by default. * [tests] Execute mmp regression tests with Xcode 9.4 since many of them are 32-bit and needs porting to 64-bit. * [mmptest] Ignore 32-bit XM tests if we don't have a 32-bit-capable Xcode. * [registrar] Add workaround for broken headers in Xcode 10 beta 1 (radar 40824697). * [mtouch] Restrict another workaround for an Xcode 10 beta 1 bug to a specific Xcode version to remove it asap. * [tests] Fix some protocol changes (public or not) find by introspection tests * [tests][intro] Fix DefaultCtorAllowed failures * [Intents] Obsolete several Intents classes in watchOS. Several existing Intents classes have been marked as unavailable in watchOS in the headers in Xcode 10 beta 1, and corresponding tests are now failing. So obsolete the managed wrapper types, and fix tests accordingly. * Fix xtro wrt previous Ietents/intro changes * [tests] Minor adjustments to mtouch tests to work with Xcode 10. * [msbuild] Update tests to cope with additional files produced by the Core ML compiler. * [msbuild] Xcode 10 doesn't support building watchOS 1 apps, so show a clear error message explaining it. Also update tests accordingly. * [coreimage] Stub new filters and exclude ?removed? ones from tests * Update GameplayKit and SpriteKit NSSecureCoding _upgrade_ and fix other non-public cases (in tests) * [tests] Ignore some GameKit selectors that don't respond anymore (but seems to be available, at least in header files) * [tests] Fix intro 32bits testing for filters resutls * [msbuild] Slightly change error message to be better English.
2018-06-09 04:45:24 +03:00
#if MONOMAC
}
#endif
}
2016-05-26 16:06:52 +03:00
}
}
[Test]
public void DatagramDefaults ()
{
TestRuntime.AssertSystemVersion (PlatformName.MacOSX, 10, 8, throwIfOtherPlatform: false);
#if __MACOS__
nint dsize = TestRuntime.CheckSystemVersion (PlatformName.MacOSX, 10, 10) ? 1327 : 1387;
#else
nint dsize = TestRuntime.CheckXcodeVersion (6, 0) ? 1327 : 1387;
#endif
2016-05-26 16:06:52 +03:00
using (var ssl = new SslContext (SslProtocolSide.Client, SslConnectionType.Datagram)) {
Assert.That (ssl.BufferedReadSize, Is.EqualTo ((nint) 0), "BufferedReadSize");
Assert.Null (ssl.Connection, "Connection");
Assert.That (ssl.DatagramWriteSize, Is.EqualTo (dsize), "DatagramWriteSize");
Assert.That (ssl.Handle, Is.Not.EqualTo (IntPtr.Zero), "Handle");
Assert.That (ssl.MaxDatagramRecordSize, Is.EqualTo ((nint) 1400), "MaxDatagramRecordSize");
Assert.That (ssl.MaxProtocol, Is.EqualTo (SslProtocol.Dtls_1_0), "MaxProtocol");
Assert.That (ssl.MinProtocol, Is.EqualTo (SslProtocol.Dtls_1_0), "MinProtocol");
Assert.That (ssl.NegotiatedCipher, Is.EqualTo (SslCipherSuite.SSL_NULL_WITH_NULL_NULL), "NegotiatedCipher");
Assert.That (ssl.NegotiatedProtocol, Is.EqualTo (SslProtocol.Unknown), "NegotiatedProtocol");
Assert.Null (ssl.PeerId, "PeerId");
Assert.That (ssl.SessionState, Is.EqualTo (SslSessionState.Idle), "SessionState");
ssl.PeerId = new byte [] { 0xff };
Assert.That (ssl.PeerId.Length, Is.EqualTo (1), "1");
// note: SSLSetPeerID (see Apple open source code) does not accept a null/zero-length value
ssl.PeerId = null;
Assert.That ((int) ssl.GetLastStatus (), Is.EqualTo (errSecParam), "set_PeerId/null");
Assert.That ((int)ssl.SetDatagramHelloCookie (new byte [33]), Is.EqualTo (-50), "cookie to long");
Assert.That (ssl.SetDatagramHelloCookie (new byte [32]), Is.EqualTo (SslStatus.Success), "tasty cookie");;
Assert.That (ssl.SetDatagramHelloCookie (new byte [1]), Is.EqualTo (SslStatus.Success), "fat free cookie");
Assert.That (ssl.SetDatagramHelloCookie (null), Is.EqualTo (SslStatus.Success), "no more cookies");
}
}
[Test]
public void SslSupportedCiphers ()
{
TestRuntime.AssertSystemVersion (PlatformName.MacOSX, 10, 8, throwIfOtherPlatform: false);
2016-05-26 16:06:52 +03:00
int ssl_client_ciphers = -1;
using (var client = new SslContext (SslProtocolSide.Client, SslConnectionType.Stream)) {
// maximum downgrade
client.MaxProtocol = client.MinProtocol;
var ciphers = client.GetSupportedCiphers ();
ssl_client_ciphers = ciphers.Count;
Assert.That (ssl_client_ciphers, Is.AtLeast (1), "GetSupportedCiphers");
// we can't really scan for SSL_* since (some of) the values are identical to TLS_
// useful the other way around
}
int ssl_server_ciphers = -1;
using (var server = new SslContext (SslProtocolSide.Server, SslConnectionType.Stream)) {
// no downgrade, shows that the ciphers are not really restriced
var ciphers = server.GetSupportedCiphers ();
ssl_server_ciphers = ciphers.Count;
Assert.That (ssl_server_ciphers, Is.AtLeast (1), "GetSupportedCiphers");
// we can't really scan for SSL_* since (some of) the values are identical to TLS_
// useful the other way around
// make sure we have names for all ciphers - except old export ones (that we do not want to promote)
// e.g. iOS 5.1 still supports them
foreach (var cipher in ciphers) {
string s = cipher.ToString ();
if (s.Length < 8)
Console.WriteLine (s);
Assert.True (s.StartsWith ("SSL_", StringComparison.Ordinal) || s.StartsWith ("TLS_", StringComparison.Ordinal), s);
}
}
Assert.That (ssl_client_ciphers, Is.EqualTo (ssl_server_ciphers), "same");
}
#if !__WATCHOS__
// This test uses sockets (TcpClient), which doesn't work on watchOS.
2016-05-26 16:06:52 +03:00
[Test]
public void Tls12 ()
{
TestRuntime.AssertSystemVersion (PlatformName.MacOSX, 10, 8, throwIfOtherPlatform: false);
2016-05-26 16:06:52 +03:00
var client = new TcpClient ("google.ca", 443);
using (NetworkStream ns = client.GetStream ())
using (var ssl = new SslContext (SslProtocolSide.Client, SslConnectionType.Stream)) {
ssl.MinProtocol = SslProtocol.Tls_1_2;
Assert.That (ssl.MinProtocol, Is.EqualTo (SslProtocol.Tls_1_2), "MinProtocol");
ssl.Connection = new SslStreamConnection (ns);
var result = ssl.Handshake ();
while (result == SslStatus.WouldBlock || result == (SslStatus) (-108)) {
// we need to ask again - but if we're too fast we'll get -108 (errSecAllocate)
Thread.Sleep (100);
// during the above call SessionState is Handshake
Assert.That (ssl.SessionState, Is.EqualTo (SslSessionState.Handshake), "Handshake/in progress");
result = ssl.Handshake ();
}
Assert.That (result, Is.EqualTo (SslStatus.Success), "Handshake/done");
// FIXME: iOS 8 beta 1 bug ?!? the state is not updated (maybe delayed?) but the code still works
//Assert.That (ssl.SessionState, Is.EqualTo (SslSessionState.Connected), "Connected");
Assert.That (ssl.NegotiatedCipher, Is.Not.EqualTo (SslCipherSuite.SSL_NULL_WITH_NULL_NULL), "NegotiatedCipher");
Assert.That (ssl.NegotiatedProtocol, Is.EqualTo (SslProtocol.Tls_1_2), "NegotiatedProtocol");
nint processed;
var data = Encoding.UTF8.GetBytes ("GET / HTTP/1.0" + Environment.NewLine + Environment.NewLine);
result = ssl.Write (data, out processed);
Assert.That (processed, Is.EqualTo ((nint) data.Length), "small buffer");
Assert.That (result, Is.EqualTo (SslStatus.Success), "Write");
data = new byte [1024];
result = ssl.Read (data, out processed);
while (result == SslStatus.WouldBlock)
result = ssl.Read (data, out processed);
Assert.That (result, Is.EqualTo (SslStatus.Success), "Read");
string s = Encoding.UTF8.GetString (data, 0, (int) processed);
// The result apparently depends on where you are: I get a 302, the bots get a 200.
Assert.That (s, Is.StringStarting ("HTTP/1.0 302 Found").Or.StringStarting ("HTTP/1.0 200 OK"), "response");
}
}
#endif // !__WATCHOS__
2016-05-26 16:06:52 +03:00
}
}