// // SecureStringTest.cs - Unit tests for System.Security.SecureString // // Author: // Sebastien Pouliot // // Copyright (C) 2005 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. // #if NET_2_0 using System; using System.Security; using NUnit.Framework; namespace MonoTests.System.Security { [TestFixture] public class SecureStringTest { private const string NotSupported = "Not supported before Windows 2000 Service Pack 3"; [Test] public void DefaultConstructor () { try { SecureString ss = new SecureString (); Assert.IsFalse (ss.IsReadOnly (), "IsReadOnly"); Assert.AreEqual (0, ss.Length, "0"); ss.AppendChar ('a'); Assert.AreEqual (1, ss.Length, "1"); ss.Clear (); Assert.AreEqual (0, ss.Length, "0b"); ss.InsertAt (0, 'b'); Assert.AreEqual (1, ss.Length, "1b"); ss.SetAt (0, 'c'); Assert.AreEqual (1, ss.Length, "1c"); Assert.AreEqual ("System.Security.SecureString", ss.ToString (), "ToString"); ss.RemoveAt (0); Assert.AreEqual (0, ss.Length, "0c"); ss.Dispose (); } catch (NotSupportedException) { Assert.Ignore (NotSupported); } } [Test] public unsafe void UnsafeConstructor () { try { SecureString ss = null; char[] data = new char[] { 'a', 'b', 'c' }; fixed (char* p = &data[0]) { ss = new SecureString (p, data.Length); } Assert.IsFalse (ss.IsReadOnly (), "IsReadOnly"); Assert.AreEqual (3, ss.Length, "3"); ss.AppendChar ('a'); Assert.AreEqual (4, ss.Length, "4"); ss.Clear (); Assert.AreEqual (0, ss.Length, "0b"); ss.InsertAt (0, 'b'); Assert.AreEqual (1, ss.Length, "1b"); ss.SetAt (0, 'c'); Assert.AreEqual (1, ss.Length, "1c"); ss.RemoveAt (0); Assert.AreEqual (0, ss.Length, "0c"); ss.Dispose (); } catch (NotSupportedException) { Assert.Ignore (NotSupported); } } [Test] [ExpectedException (typeof (ArgumentNullException))] public unsafe void UnsafeConstructor_Null () { new SecureString (null, 0); } [Test] [ExpectedException (typeof (ArgumentOutOfRangeException))] public unsafe void UnsafeConstructor_Negative () { char[] data = new char[] { 'a', 'b', 'c' }; fixed (char* p = &data[0]) { new SecureString (p, -1); } } [Test] [ExpectedException (typeof (ArgumentOutOfRangeException))] public unsafe void UnsafeConstructor_BiggerThanMax () { char[] data = new char[] { 'a', 'b', 'c' }; fixed (char* p = &data[0]) { new SecureString (p, UInt16.MaxValue + 2); } } private SecureString max; private unsafe SecureString GetMaxLength () { if (max == null) { int maxlength = UInt16.MaxValue + 1; char[] data = new char[maxlength]; fixed (char* p = &data[0]) { max = new SecureString (p, maxlength); } // note: don't try a loop of AppendChar with that size ;-) } return max; } [Test] [ExpectedException (typeof (ArgumentOutOfRangeException))] public void AppendChar_BiggerThanMax () { SecureString ss = GetMaxLength (); ss.AppendChar ('a'); } [Test] [ExpectedException (typeof (ArgumentOutOfRangeException))] public void InsertAt_Negative () { SecureString ss = new SecureString (); ss.InsertAt (-1, 'a'); } [Test] [ExpectedException (typeof (ArgumentOutOfRangeException))] public void InsertAt_BiggerThanLength () { SecureString ss = new SecureString (); ss.InsertAt (1, 'a'); } [Test] [ExpectedException (typeof (ArgumentOutOfRangeException))] public void SetAt_Negative () { SecureString ss = new SecureString (); ss.SetAt (-1, 'a'); } [Test] [ExpectedException (typeof (ArgumentOutOfRangeException))] public void SetAt_BiggerThanLength () { SecureString ss = new SecureString (); ss.SetAt (1, 'a'); } [Test] [ExpectedException (typeof (ArgumentOutOfRangeException))] public void RemoveAt_Negative () { SecureString ss = new SecureString (); ss.RemoveAt (-1); } [Test] [ExpectedException (typeof (ArgumentOutOfRangeException))] public void RemoveAt_BiggerThanLength () { SecureString ss = new SecureString (); ss.RemoveAt (1); } [Test] [ExpectedException (typeof (ArgumentOutOfRangeException))] public void InsertAt_BiggerThanMax () { SecureString ss = GetMaxLength (); ss.InsertAt (ss.Length, 'a'); } private SecureString GetReadOnly () { SecureString ss = new SecureString (); ss.MakeReadOnly (); return ss; } [Test] public void ReadOnly () { try { SecureString ss = GetReadOnly (); Assert.IsTrue (ss.IsReadOnly (), "IsReadOnly"); Assert.AreEqual (0, ss.Length, "0"); ss.Dispose (); } catch (NotSupportedException) { Assert.Ignore (NotSupported); } } [Test] [ExpectedException (typeof (InvalidOperationException))] public void ReadOnly_AppendChar () { SecureString ss = GetReadOnly (); ss.AppendChar ('a'); } [Test] [ExpectedException (typeof (InvalidOperationException))] public void ReadOnly_Clear () { SecureString ss = GetReadOnly (); ss.Clear (); } [Test] [ExpectedException (typeof (InvalidOperationException))] public void ReadOnly_InsertAt () { SecureString ss = GetReadOnly (); ss.InsertAt (0, 'a'); } [Test] [ExpectedException (typeof (InvalidOperationException))] public void ReadOnly_SetAt () { SecureString ss = GetReadOnly (); ss.SetAt (0, 'a'); } [Test] [ExpectedException (typeof (InvalidOperationException))] public void ReadOnly_RemoveAt () { SecureString ss = GetReadOnly (); ss.RemoveAt (0); } private SecureString GetDisposed () { SecureString ss = new SecureString (); ss.Dispose (); return ss; } [Test] public void Disposed () { try { SecureString ss = GetDisposed (); ss.Dispose (); } catch (NotSupportedException) { Assert.Ignore (NotSupported); } } [Test] [ExpectedException (typeof (ObjectDisposedException))] public void Disposed_AppendChar () { SecureString ss = GetDisposed (); ss.AppendChar ('a'); } [Test] [ExpectedException (typeof (ObjectDisposedException))] public void Disposed_Clear () { SecureString ss = GetDisposed (); ss.Clear (); } [Test] [ExpectedException (typeof (ObjectDisposedException))] public void Disposed_InsertAt () { SecureString ss = GetDisposed (); ss.InsertAt (0, 'a'); } [Test] [ExpectedException (typeof (ObjectDisposedException))] public void Disposed_IsReadOnly () { SecureString ss = GetDisposed (); Assert.IsFalse (ss.IsReadOnly (), "IsReadOnly"); } [Test] [ExpectedException (typeof (ObjectDisposedException))] public void Disposed_Length () { SecureString ss = GetDisposed (); Assert.AreEqual (0, ss.Length, "Length"); } [Test] [ExpectedException (typeof (ObjectDisposedException))] public void Disposed_SetAt () { SecureString ss = GetDisposed (); ss.SetAt (0, 'a'); } [Test] [ExpectedException (typeof (ObjectDisposedException))] public void Disposed_RemoveAt () { SecureString ss = GetDisposed (); ss.RemoveAt (0); } } } #endif