Esempio n. 1
0
        public void GenerateKeyPairTooLargeRSA()
        {
            SecKey private_key;
            SecKey public_key;

            using (var record = new SecRecord(SecKind.Key)) {
                record.KeyType = SecKeyType.RSA;
                // maximum documented as 2048, .NET maximum is 16384
                record.KeySizeInBits = 16384;
                Assert.That(SecKey.GenerateKeyPair(record.ToDictionary(), out public_key, out private_key), Is.EqualTo(SecStatusCode.Param), "16384");
                record.KeySizeInBits = 8192;
                if (TestRuntime.CheckXcodeVersion(7, 0))
                {
                    // It seems iOS 9 supports 8192, but it takes a long time to generate (~40 seconds on my iPad Air 2), so skip it.
//					Assert.That (SecKey.GenerateKeyPair (record.ToDictionary (), out public_key, out private_key), Is.EqualTo (SecStatusCode.Success), "8192");
                }
                else
                {
                    Assert.That(SecKey.GenerateKeyPair(record.ToDictionary(), out public_key, out private_key), Is.EqualTo(SecStatusCode.Param), "8192");
                }
            }

            /* On iOS 7.1 the device console logs will show:
             *
             * Mar 18 08:27:30 Mercure monotouchtest[1397] <Warning>:  SecRSAPrivateKeyInit Invalid or missing key size in: {
             *      bsiz = 16384;
             *      class = keys;
             *      type = 42;
             *  }
             * Mar 18 08:27:30 Mercure monotouchtest[1397] <Warning>:  SecKeyCreate init RSAPrivateKey key: -50
             */
        }
Esempio n. 2
0
        public void SignVerifyRSAMinPKCS1SHA1()
        {
            SecKey private_key;
            SecKey public_key;
            var    label = $"KeyTest.SignVerifyRSAMinPKCS1SHA1-{CFBundle.GetMain ().Identifier}-{GetType ().FullName}-{Process.GetCurrentProcess ().Id}";

            try {
                using (var record = new SecRecord(SecKind.Key)) {
                    record.KeyType       = SecKeyType.RSA;
                    record.KeySizeInBits = MinRsaKeySize;                     // it's not a performance test :)
                    record.Label         = label;

                    Assert.That(SecKey.GenerateKeyPair(record.ToDictionary(), out public_key, out private_key), Is.EqualTo(SecStatusCode.Success), "GenerateKeyPair");

                    byte [] hash = new byte [20] {
                        1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
                    };
                    byte [] sign;
                    Assert.That(private_key.RawSign(SecPadding.PKCS1SHA1, hash, out sign), Is.EqualTo(SecStatusCode.Success), "RawSign");
                    Assert.That(public_key.RawVerify(SecPadding.PKCS1SHA1, hash, sign), Is.EqualTo(SecStatusCode.Success), "RawVerify");

                    var empty = new byte [0];
                    Assert.That(private_key.RawSign(SecPadding.PKCS1, empty, out sign), Is.EqualTo(SecStatusCode.Success), "RawSign-empty");
                    // results vary per iOS version - but that's out of our control and we only care that it does not crash
                    public_key.RawVerify(SecPadding.PKCS1SHA1, empty, empty);

                    private_key.Dispose();
                    public_key.Dispose();
                }
            } finally {
                // Clean up after us
                DeleteKeysWithLabel(label);
            }
        }
Esempio n. 3
0
        public void EncryptTooLarge()
        {
            SecKey private_key;
            SecKey public_key;

            using (var record = new SecRecord(SecKind.Key)) {
                record.KeyType = SecKeyType.RSA;
#if MONOMAC
                record.KeySizeInBits = 1024;
#else
                record.KeySizeInBits = 512;                 // it's not a performance test :)
#endif

                Assert.That(SecKey.GenerateKeyPair(record.ToDictionary(), out public_key, out private_key), Is.EqualTo(SecStatusCode.Success), "GenerateKeyPair");

#if MONOMAC
                byte [] plain = new byte [128];                // 128 * 8 == 1024 - but there's the padding to consider
#else
                byte [] plain = new byte [64];                 // 64 * 8 == 512 - but there's the padding to consider
#endif
                byte [] cipher;
                Assert.That(public_key.Encrypt(SecPadding.PKCS1, plain, out cipher), Is.EqualTo(SecStatusCode.Param), "Encrypt");

                public_key.Dispose();
                private_key.Dispose();
            }
        }
Esempio n. 4
0
        public void RoundtripRSA1024OAEP()
        {
            SecKey private_key;
            SecKey public_key;

            using (var record = new SecRecord(SecKind.Key)) {
                record.KeyType       = SecKeyType.RSA;
                record.KeySizeInBits = 1024;                 // it's not a performance test :)

                Assert.That(SecKey.GenerateKeyPair(record.ToDictionary(), out public_key, out private_key), Is.EqualTo(SecStatusCode.Success), "GenerateKeyPair");

                byte [] plain = new byte [0];
                byte [] cipher;
                if (TestRuntime.CheckXcodeVersion(8, 0))
                {
                    Assert.True(public_key.IsAlgorithmSupported(SecKeyOperationType.Encrypt, SecKeyAlgorithm.RsaEncryptionOaepSha1), "public/IsAlgorithmSupported/Encrypt");
                    // I would have expect false
                    Assert.True(public_key.IsAlgorithmSupported(SecKeyOperationType.Decrypt, SecKeyAlgorithm.RsaEncryptionOaepSha1), "public/IsAlgorithmSupported/Decrypt");
                }
                Assert.That(public_key.Encrypt(SecPadding.OAEP, plain, out cipher), Is.EqualTo(SecStatusCode.Success), "Encrypt");
                public_key.Dispose();

                byte[] result;
                if (TestRuntime.CheckXcodeVersion(8, 0))
                {
                    Assert.False(private_key.IsAlgorithmSupported(SecKeyOperationType.Encrypt, SecKeyAlgorithm.RsaEncryptionOaepSha1), "private/IsAlgorithmSupported/Encrypt");
                    Assert.True(private_key.IsAlgorithmSupported(SecKeyOperationType.Decrypt, SecKeyAlgorithm.RsaEncryptionOaepSha1), "private/IsAlgorithmSupported/Decrypt");
                }
                Assert.That(private_key.Decrypt(SecPadding.OAEP, cipher, out result), Is.EqualTo(SecStatusCode.Success), "Decrypt");
                Assert.That(plain, Is.EqualTo(result), "match");
                private_key.Dispose();
            }
        }
Esempio n. 5
0
        public void SignVerifyRSA512PKCS1SHA1()
        {
            SecKey private_key;
            SecKey public_key;

            using (var record = new SecRecord(SecKind.Key)) {
                record.KeyType       = SecKeyType.RSA;
                record.KeySizeInBits = 512;                 // it's not a performance test :)

                Assert.That(SecKey.GenerateKeyPair(record.ToDictionary(), out public_key, out private_key), Is.EqualTo(SecStatusCode.Success), "GenerateKeyPair");

                byte [] hash = new byte [20] {
                    1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
                };
                byte [] sign;
                Assert.That(private_key.RawSign(SecPadding.PKCS1SHA1, hash, out sign), Is.EqualTo(SecStatusCode.Success), "RawSign");
                Assert.That(public_key.RawVerify(SecPadding.PKCS1SHA1, hash, sign), Is.EqualTo(SecStatusCode.Success), "RawVerify");

                var empty = new byte [0];
                if (TestRuntime.CheckXcodeVersion(8, 0))
                {
                    Assert.That(private_key.RawSign(SecPadding.PKCS1SHA1, empty, out sign), Is.EqualTo(SecStatusCode.Success), "RawSign-empty");
                    Assert.That(public_key.RawVerify(SecPadding.PKCS1SHA1, empty, empty), Is.EqualTo(SecStatusCode.Success), "RawVerify-empty");
                }
                else
                {
                    Assert.That(private_key.RawSign(SecPadding.PKCS1SHA1, empty, out sign), Is.EqualTo(SecStatusCode.Param), "RawSign-empty");
                    Assert.That(public_key.RawVerify(SecPadding.PKCS1SHA1, empty, empty), Is.EqualTo(SecStatusCode.Param), "RawVerify-empty");
                }

                private_key.Dispose();
                public_key.Dispose();
            }
        }
Esempio n. 6
0
        public void SignVerifyRSAMinPKCS1SHA1()
        {
            SecKey private_key;
            SecKey public_key;

            using (var record = new SecRecord(SecKind.Key)) {
                record.KeyType       = SecKeyType.RSA;
                record.KeySizeInBits = MinRsaKeySize;                 // it's not a performance test :)

                Assert.That(SecKey.GenerateKeyPair(record.ToDictionary(), out public_key, out private_key), Is.EqualTo(SecStatusCode.Success), "GenerateKeyPair");

                byte [] hash = new byte [20] {
                    1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
                };
                byte [] sign;
                Assert.That(private_key.RawSign(SecPadding.PKCS1SHA1, hash, out sign), Is.EqualTo(SecStatusCode.Success), "RawSign");
                Assert.That(public_key.RawVerify(SecPadding.PKCS1SHA1, hash, sign), Is.EqualTo(SecStatusCode.Success), "RawVerify");

                var empty = new byte [0];
                Assert.That(private_key.RawSign(SecPadding.PKCS1, empty, out sign), Is.EqualTo(SecStatusCode.Success), "RawSign-empty");
                // results vary per iOS version - but that's out of our control and we only care that it does not crash
                public_key.RawVerify(SecPadding.PKCS1SHA1, empty, empty);

                private_key.Dispose();
                public_key.Dispose();
            }
        }
Esempio n. 7
0
        public void SignVerifyECSHA1()
        {
            SecKey private_key;
            SecKey public_key;

            using (var record = new SecRecord(SecKind.Key)) {
                record.KeyType       = SecKeyType.EC;
                record.KeySizeInBits = 256;                 // it's not a performance test :)

                Assert.That(SecKey.GenerateKeyPair(record.ToDictionary(), out public_key, out private_key), Is.EqualTo(SecStatusCode.Success), "GenerateKeyPair");

                byte [] hash = new byte [20] {
                    1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
                };
                byte [] sign;
                // PKCS1SHA1 implies RSA (oid)
                Assert.That(private_key.RawSign(SecPadding.PKCS1, hash, out sign), Is.EqualTo(SecStatusCode.Success), "RawSign");
                Assert.That(public_key.RawVerify(SecPadding.PKCS1, hash, sign), Is.EqualTo(SecStatusCode.Success), "RawVerify");

                var empty = new byte [0];
                // there does not seem to be a length-check on PKCS1, likely because not knowning the hash algorithm makes it harder
                Assert.That(private_key.RawSign(SecPadding.PKCS1, empty, out sign), Is.EqualTo(SecStatusCode.Success), "RawSign-empty");
                // results vary per iOS version - but that's out of our control and we only care that it does not crash
                public_key.RawVerify(SecPadding.PKCS1, empty, empty);

                private_key.Dispose();
                public_key.Dispose();
            }
        }
Esempio n. 8
0
        public void EncryptTooLarge()
        {
            SecKey private_key;
            SecKey public_key;

            using (var record = new SecRecord(SecKind.Key)) {
                record.KeyType       = SecKeyType.RSA;
                record.KeySizeInBits = MinRsaKeySize;                 // it's not a performance test :)

                Assert.That(SecKey.GenerateKeyPair(record.ToDictionary(), out public_key, out private_key), Is.EqualTo(SecStatusCode.Success), "GenerateKeyPair");

                byte [] plain = new byte [MinRsaKeySize / 8];
                byte [] cipher;
                var     rv             = public_key.Encrypt(SecPadding.PKCS1, plain, out cipher);
                var     expectedStatus = SecStatusCode.Param;
#if __MACOS__
                if (!TestRuntime.CheckSystemVersion(PlatformName.MacOSX, 10, 8))
                {
                    expectedStatus = SecStatusCode.Success;
                }
                else if (!TestRuntime.CheckSystemVersion(PlatformName.MacOSX, 10, 12))
                {
                    expectedStatus = SecStatusCode.OutputLengthError;
                }
#endif
                Assert.That(rv, Is.EqualTo(expectedStatus), "Encrypt");

                public_key.Dispose();
                private_key.Dispose();
            }
        }
Esempio n. 9
0
        public void Identity()
        {
            var rec = new SecRecord(SecKind.Identity)
            {
                Account   = "Username",
                ValueData = NSData.FromString("Password"),
            };

            // prior to iOS7 you had to deal without the class
            using (var dict = rec.ToDictionary()) {
                var hasIdnt = true;
#if !__MACOS__
                if (!TestRuntime.CheckXcodeVersion(5, 0))
                {
                    hasIdnt = false;
                }
#endif
                if (hasIdnt)
                {
                    Assert.That(dict ["class"].ToString(), Is.EqualTo("idnt"), "idnt");
                }
                else
                {
                    Assert.Null(dict ["class"], "idnt");
                }
            }
        }
Esempio n. 10
0
        public void RoundtripRSA1024OAEP()
        {
            SecKey private_key;
            SecKey public_key;
            var    label = $"KeyTest.RoundtripRSA1024OAEP-{CFBundle.GetMain ().Identifier}-{GetType ().FullName}-{Process.GetCurrentProcess ().Id}";

            try {
                using (var record = new SecRecord(SecKind.Key)) {
                    record.KeyType       = SecKeyType.RSA;
                    record.KeySizeInBits = 1024;                     // it's not a performance test :)
                    record.Label         = label;

                    Assert.That(SecKey.GenerateKeyPair(record.ToDictionary(), out public_key, out private_key), Is.EqualTo(SecStatusCode.Success), "GenerateKeyPair");

                    byte [] plain = new byte [0];
                    byte [] cipher;
                    if (TestRuntime.CheckXcodeVersion(8, 0))
                    {
                        Assert.True(public_key.IsAlgorithmSupported(SecKeyOperationType.Encrypt, SecKeyAlgorithm.RsaEncryptionOaepSha1), "public/IsAlgorithmSupported/Encrypt");
                        // I would have expect false
#if MONOMAC
                        Assert.That(public_key.IsAlgorithmSupported(SecKeyOperationType.Decrypt, SecKeyAlgorithm.RsaEncryptionOaepSha1), Is.EqualTo(TestRuntime.CheckSystemVersion(PlatformName.MacOSX, 10, 13)), "public/IsAlgorithmSupported/Decrypt");
#else
                        Assert.True(public_key.IsAlgorithmSupported(SecKeyOperationType.Decrypt, SecKeyAlgorithm.RsaEncryptionOaepSha1), "public/IsAlgorithmSupported/Decrypt");
#endif
                    }
                    Assert.That(public_key.Encrypt(SecPadding.OAEP, plain, out cipher), Is.EqualTo(SecStatusCode.Success), "Encrypt");
                    public_key.Dispose();

                    byte[] result;
                    if (TestRuntime.CheckXcodeVersion(8, 0))
                    {
                        Assert.False(private_key.IsAlgorithmSupported(SecKeyOperationType.Encrypt, SecKeyAlgorithm.RsaEncryptionOaepSha1), "private/IsAlgorithmSupported/Encrypt");
                        Assert.True(private_key.IsAlgorithmSupported(SecKeyOperationType.Decrypt, SecKeyAlgorithm.RsaEncryptionOaepSha1), "private/IsAlgorithmSupported/Decrypt");
                    }
                    Assert.That(private_key.Decrypt(SecPadding.OAEP, cipher, out result), Is.EqualTo(SecStatusCode.Success), "Decrypt");
                    var expectEmpty = false;
#if __MACOS__
                    if (!TestRuntime.CheckSystemVersion(PlatformName.MacOSX, 10, 12))
                    {
                        expectEmpty = true;
                    }
#endif
                    if (expectEmpty)
                    {
                        Assert.That(plain, Is.EqualTo(new byte [0]), "match (empty)");
                    }
                    else
                    {
                        Assert.That(plain, Is.EqualTo(result), "match");
                    }
                    private_key.Dispose();
                }
            } finally {
                // Clean up after us
                DeleteKeysWithLabel(label);
            }
        }
Esempio n. 11
0
        public void GenerateKeyPairTooLargeRSA()
        {
            SecKey private_key;
            SecKey public_key;
            var    label = $"KeyTest.GenerateKeyPairTooLargeRSA-{CFBundle.GetMain ().Identifier}-{GetType ().FullName}-{Process.GetCurrentProcess ().Id}";

            try {
                using (var record = new SecRecord(SecKind.Key)) {
                    record.KeyType = SecKeyType.RSA;
                    // maximum documented as 2048, .NET maximum is 16384
                    record.KeySizeInBits = 16384;
                    record.Label         = label;
                    Assert.That(SecKey.GenerateKeyPair(record.ToDictionary(), out public_key, out private_key), Is.EqualTo(SecStatusCode.Param), "16384");
                    record.KeySizeInBits = 8192;
                    if (TestRuntime.CheckXcodeVersion(7, 0))
                    {
                        // It seems iOS 9 supports 8192, but it takes a long time to generate (~40 seconds on my iPad Air 2), so skip it.
                        //					Assert.That (SecKey.GenerateKeyPair (record.ToDictionary (), out public_key, out private_key), Is.EqualTo (SecStatusCode.Success), "8192");
                    }
                    else
                    {
                        Assert.That(SecKey.GenerateKeyPair(record.ToDictionary(), out public_key, out private_key), Is.EqualTo(SecStatusCode.Param), "8192");
                    }
                }

                /* On iOS 7.1 the device console logs will show:
                 *
                 * Mar 18 08:27:30 Mercure monotouchtest[1397] <Warning>:  SecRSAPrivateKeyInit Invalid or missing key size in: {
                 *      bsiz = 16384;
                 *      class = keys;
                 *      type = 42;
                 *  }
                 * Mar 18 08:27:30 Mercure monotouchtest[1397] <Warning>:  SecKeyCreate init RSAPrivateKey key: -50
                 */
            } finally {
                // Clean up after us
                DeleteKeysWithLabel(label);
            }
        }
Esempio n. 12
0
        public void BenchmarkNative4096()
        {
            SecKey private_key;
            SecKey public_key;
            var    label = $"KeyTest.BenchmarkNative4096-{CFBundle.GetMain ().Identifier}-{GetType ().FullName}-{Process.GetCurrentProcess ().Id}";

            try {
                using (var record = new SecRecord(SecKind.Key)) {
                    record.KeyType       = SecKeyType.RSA;
                    record.KeySizeInBits = 4096;
                    record.Label         = label;

                    var chrono = new Stopwatch();
                    chrono.Start();
                    Assert.That(SecKey.GenerateKeyPair(record.ToDictionary(), out public_key, out private_key), Is.EqualTo(SecStatusCode.Success), "GenerateKeyPair");
                    Console.WriteLine("Key generation {0} ms", chrono.ElapsedMilliseconds);
                    chrono.Restart();

                    byte [] hash = new byte [20] {
                        1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
                    };
                    byte[] result;
                    public_key.Encrypt(SecPadding.OAEP, hash, out result);
                    Console.WriteLine("Encrypt {0} ms", chrono.ElapsedMilliseconds);
                    chrono.Restart();

                    private_key.Decrypt(SecPadding.OAEP, result, out result);
                    Console.WriteLine("Decrypt {0} ms", chrono.ElapsedMilliseconds);
                    chrono.Restart();

                    private_key.RawSign(SecPadding.PKCS1SHA1, hash, out result);
                    Console.WriteLine("Sign {0} ms", chrono.ElapsedMilliseconds);
                    chrono.Restart();

                    public_key.RawVerify(SecPadding.PKCS1SHA1, hash, result);
                    Console.WriteLine("Verify {0} ms", chrono.ElapsedMilliseconds);

                    private_key.Dispose();
                    public_key.Dispose();
                }
            } finally {
                // Clean up after us
                DeleteKeysWithLabel(label);
            }
        }
Esempio n. 13
0
        public void EncryptTooLarge()
        {
            SecKey private_key;
            SecKey public_key;

            using (var record = new SecRecord(SecKind.Key)) {
                record.KeyType       = SecKeyType.RSA;
                record.KeySizeInBits = MinRsaKeySize;                 // it's not a performance test :)

                Assert.That(SecKey.GenerateKeyPair(record.ToDictionary(), out public_key, out private_key), Is.EqualTo(SecStatusCode.Success), "GenerateKeyPair");

                byte [] plain = new byte [MinRsaKeySize / 8];
                byte [] cipher;
                Assert.That(public_key.Encrypt(SecPadding.PKCS1, plain, out cipher), Is.EqualTo(SecStatusCode.Param), "Encrypt");

                public_key.Dispose();
                private_key.Dispose();
            }
        }
Esempio n. 14
0
        public void Identity()
        {
            var rec = new SecRecord(SecKind.Identity)
            {
                Account   = "Username",
                ValueData = NSData.FromString("Password"),
            };

            // prior to iOS7 you had to deal without the class
            using (var dict = rec.ToDictionary()) {
                if (TestRuntime.CheckSystemAndSDKVersion(7, 0))
                {
                    Assert.That(dict ["class"].ToString(), Is.EqualTo("idnt"), "idnt");
                }
                else
                {
                    Assert.Null(dict ["class"], "idnt");
                }
            }
        }
Esempio n. 15
0
        public void EncryptTooLarge()
        {
            SecKey private_key;
            SecKey public_key;
            var    label = $"KeyTest.EncryptTooLarge-{CFBundle.GetMain ().Identifier}-{GetType ().FullName}-{Process.GetCurrentProcess ().Id}";

            try {
                using (var record = new SecRecord(SecKind.Key)) {
                    record.KeyType       = SecKeyType.RSA;
                    record.KeySizeInBits = MinRsaKeySize;                     // it's not a performance test :)
                    record.Label         = label;

                    Assert.That(SecKey.GenerateKeyPair(record.ToDictionary(), out public_key, out private_key), Is.EqualTo(SecStatusCode.Success), "GenerateKeyPair");

                    byte [] plain = new byte [MinRsaKeySize / 8];
                    byte [] cipher;
                    var     rv             = public_key.Encrypt(SecPadding.PKCS1, plain, out cipher);
                    var     expectedStatus = SecStatusCode.Param;

#if __MACOS__
                    if (!TestRuntime.CheckSystemVersion(PlatformName.MacOSX, 10, 8))
                    {
                        expectedStatus = SecStatusCode.Success;
                    }
                    else if (!TestRuntime.CheckSystemVersion(PlatformName.MacOSX, 10, 12))
                    {
                        expectedStatus = SecStatusCode.OutputLengthError;
                    }
#endif
                    Assert.That(rv, Is.EqualTo(expectedStatus), "Encrypt");

                    public_key.Dispose();
                    private_key.Dispose();
                }
            } finally {
                // Clean up after us
                DeleteKeysWithLabel(label);
            }
        }
Esempio n. 16
0
        public void RoundtripRSA1024OAEP()
        {
            SecKey private_key;
            SecKey public_key;

            using (var record = new SecRecord(SecKind.Key)) {
                record.KeyType       = SecKeyType.RSA;
                record.KeySizeInBits = 1024;                 // it's not a performance test :)

                Assert.That(SecKey.GenerateKeyPair(record.ToDictionary(), out public_key, out private_key), Is.EqualTo(SecStatusCode.Success), "GenerateKeyPair");

                byte [] plain = new byte [0];
                byte [] cipher;
                Assert.That(public_key.Encrypt(SecPadding.OAEP, plain, out cipher), Is.EqualTo(SecStatusCode.Success), "Encrypt");
                public_key.Dispose();

                byte[] result;
                Assert.That(private_key.Decrypt(SecPadding.OAEP, cipher, out result), Is.EqualTo(SecStatusCode.Success), "Decrypt");
                Assert.That(plain, Is.EqualTo(result), "match");
                private_key.Dispose();
            }
        }
Esempio n. 17
0
        public void BenchmarkNative4096()
        {
            SecKey private_key;
            SecKey public_key;

            using (var record = new SecRecord(SecKind.Key)) {
                record.KeyType       = SecKeyType.RSA;
                record.KeySizeInBits = 4096;

                var chrono = new Stopwatch();
                chrono.Start();
                Assert.That(SecKey.GenerateKeyPair(record.ToDictionary(), out public_key, out private_key), Is.EqualTo(SecStatusCode.Success), "GenerateKeyPair");
                Console.WriteLine("Key generation {0} ms", chrono.ElapsedMilliseconds);
                chrono.Restart();

                byte [] hash = new byte [20] {
                    1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
                };
                byte[] result;
                public_key.Encrypt(SecPadding.OAEP, hash, out result);
                Console.WriteLine("Encrypt {0} ms", chrono.ElapsedMilliseconds);
                chrono.Restart();

                private_key.Decrypt(SecPadding.OAEP, result, out result);
                Console.WriteLine("Decrypt {0} ms", chrono.ElapsedMilliseconds);
                chrono.Restart();

                private_key.RawSign(SecPadding.PKCS1SHA1, hash, out result);
                Console.WriteLine("Sign {0} ms", chrono.ElapsedMilliseconds);
                chrono.Restart();

                public_key.RawVerify(SecPadding.PKCS1SHA1, hash, result);
                Console.WriteLine("Verify {0} ms", chrono.ElapsedMilliseconds);

                private_key.Dispose();
                public_key.Dispose();
            }
        }
Esempio n. 18
0
        public void SignVerifyECSHA1()
        {
            TestRuntime.AssertSystemVersion(PlatformName.MacOSX, 10, 9, throwIfOtherPlatform: false);

            SecKey private_key;
            SecKey public_key;
            var    label = $"KeyTest.SignVerifyECSHA1-{CFBundle.GetMain ().Identifier}-{GetType ().FullName}-{Process.GetCurrentProcess ().Id}";

            try {
                using (var record = new SecRecord(SecKind.Key)) {
                    record.KeyType       = SecKeyType.EC;
                    record.KeySizeInBits = 256;                     // it's not a performance test :)
                    record.Label         = label;

                    Assert.That(SecKey.GenerateKeyPair(record.ToDictionary(), out public_key, out private_key), Is.EqualTo(SecStatusCode.Success), "GenerateKeyPair");

                    byte [] hash = new byte [20] {
                        1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
                    };
                    byte [] sign;
                    // PKCS1SHA1 implies RSA (oid)
                    Assert.That(private_key.RawSign(SecPadding.PKCS1, hash, out sign), Is.EqualTo(SecStatusCode.Success), "RawSign");
                    Assert.That(public_key.RawVerify(SecPadding.PKCS1, hash, sign), Is.EqualTo(SecStatusCode.Success), "RawVerify");

                    var empty = new byte [0];
                    // there does not seem to be a length-check on PKCS1, likely because not knowning the hash algorithm makes it harder
                    Assert.That(private_key.RawSign(SecPadding.PKCS1, empty, out sign), Is.EqualTo(SecStatusCode.Success), "RawSign-empty");
                    // results vary per iOS version - but that's out of our control and we only care that it does not crash
                    public_key.RawVerify(SecPadding.PKCS1, empty, empty);

                    private_key.Dispose();
                    public_key.Dispose();
                }
            } finally {
                // Clean up after us
                DeleteKeysWithLabel(label);
            }
        }
Esempio n. 19
0
        public void SignVerifyECSHA1()
        {
            SecKey private_key;
            SecKey public_key;

            using (var record = new SecRecord(SecKind.Key)) {
                record.KeyType       = SecKeyType.EC;
                record.KeySizeInBits = 256;                 // it's not a performance test :)

                Assert.That(SecKey.GenerateKeyPair(record.ToDictionary(), out public_key, out private_key), Is.EqualTo(SecStatusCode.Success), "GenerateKeyPair");

                byte [] hash = new byte [20] {
                    1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
                };
                byte [] sign;
                // PKCS1SHA1 implies RSA (oid)
                Assert.That(private_key.RawSign(SecPadding.PKCS1, hash, out sign), Is.EqualTo(SecStatusCode.Success), "RawSign");
                Assert.That(public_key.RawVerify(SecPadding.PKCS1, hash, sign), Is.EqualTo(SecStatusCode.Success), "RawVerify");

                var empty = new byte [0];
                // there does not seem to be a length-check on PKCS1, likely because not knowning the hash algorithm makes it harder
                Assert.That(private_key.RawSign(SecPadding.PKCS1, empty, out sign), Is.EqualTo(SecStatusCode.Success), "RawSign-empty");
                if (TestRuntime.CheckXcodeVersion(8, 0))
                {
                    Assert.That(public_key.RawVerify(SecPadding.PKCS1, empty, empty), Is.EqualTo(SecStatusCode.Success), "RawVerify-empty");
                }
                else
                {
                    // but that does not work at verification time
                    Assert.That(public_key.RawVerify(SecPadding.PKCS1, empty, empty), Is.EqualTo((SecStatusCode)(-9809)), "RawVerify-empty");
                }

                private_key.Dispose();
                public_key.Dispose();
            }
        }
        private byte[] GenerateKeyPairCore(string name)
        {
            using (var parameters = new SecRecord(SecKind.Key))
            {
                parameters.AccessControl = new SecAccessControl(SecAccessible.WhenPasscodeSetThisDeviceOnly, SecAccessControlCreateFlags.TouchIDCurrentSet | SecAccessControlCreateFlags.PrivateKeyUsage);
                parameters.KeyType       = SecKeyType.EC;
                parameters.KeySizeInBits = 256;
                parameters.TokenID       = SecTokenID.SecureEnclave;

                var privateKeyParameters = new NSMutableDictionary();
                privateKeyParameters.Add(kSecAttrApplicationTag, new NSString($"{name}_priv"));
                privateKeyParameters.Add(kSecAttrIsPermanent, NSNumber.FromBoolean(true));

                var publicKeyParameters = new NSMutableDictionary();
                publicKeyParameters.Add(kSecAttrApplicationTag, new NSString($"{name}_pub"));
                publicKeyParameters.Add(kSecAttrIsPermanent, NSNumber.FromBoolean(false));

                var mutableDictionary = (NSMutableDictionary)parameters.ToDictionary();
                mutableDictionary.Add(kSecPrivateKeyAttrs, new NSDictionary(privateKeyParameters));
                mutableDictionary.Add(kSecPublicKeyAttrs, new NSDictionary(publicKeyParameters));

                var result = SecKey.GenerateKeyPair((NSDictionary)mutableDictionary, out var publicKey, out var privateKey);

                if (result == SecStatusCode.Success)
                {
                    privateKey.Dispose();

                    using (var record = new SecRecord(SecKind.Key))
                    {
                        record.KeyClass    = SecKeyClass.Public;
                        record.KeyType     = SecKeyType.EC;
                        record.IsPermanent = false;
                        record.Label       = "Public Key";
                        record.SetValueRef(publicKey);

                        var dict = (NSMutableDictionary)record.ToDictionary();
                        dict.Add(kSecReturnData, NSNumber.FromBoolean(true));

                        var status = SecItemAdd(dict.Handle, out var publicKeyDataPtr);

                        publicKey.Dispose();

                        if (status == SecStatusCode.Success)
                        {
                            var publicKeyData = ObjCRuntime.Runtime.GetINativeObject <NSData>(publicKeyDataPtr, true);

                            if (publicKeyData != null)
                            {
                                // Apple's SecurityFramework uses raw keys which need to be wrapped in proper ASN.1 for outside consumption
                                // See : https://forums.developer.apple.com/thread/8030

                                var header = NSData.FromArray(new byte[] { 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01,
                                                                           0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00 });

                                var buffer = new NSMutableData(header.Length + publicKeyData.Length);
                                buffer.AppendData(header);
                                buffer.AppendData(publicKeyData);

                                return(buffer.ToArray());
                            }
                        }

                        return(null);
                    }
                }
                else
                {
                    throw new SecurityException(result);
                }
            }
        }
Esempio n. 21
0
        public void RoundtripRSAMinPKCS1()
        {
            NSError error;
            SecKey  private_key;
            SecKey  public_key;
            var     label = $"KeyTest.RoundtripRSAMinPKCS1-{CFBundle.GetMain ().Identifier}-{GetType ().FullName}-{Process.GetCurrentProcess ().Id}";

            try {
                using (var record = new SecRecord(SecKind.Key)) {
                    record.KeyType       = SecKeyType.RSA;
                    record.KeySizeInBits = MinRsaKeySize;                     // it's not a performance test :)
                    record.Label         = label;

                    Assert.That(SecKey.GenerateKeyPair(record.ToDictionary(), out public_key, out private_key), Is.EqualTo(SecStatusCode.Success), "GenerateKeyPair");

                    byte [] plain = new byte [20] {
                        1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
                    };
                    byte [] cipher;
                    if (TestRuntime.CheckXcodeVersion(8, 0))
                    {
                        Assert.True(public_key.IsAlgorithmSupported(SecKeyOperationType.Encrypt, SecKeyAlgorithm.RsaEncryptionPkcs1), "public/IsAlgorithmSupported/Encrypt");

#if MONOMAC
                        Assert.That(public_key.IsAlgorithmSupported(SecKeyOperationType.Decrypt, SecKeyAlgorithm.RsaEncryptionPkcs1), Is.EqualTo(TestRuntime.CheckSystemVersion(PlatformName.MacOSX, 10, 13)), "public/IsAlgorithmSupported/Decrypt");

                        using (var pub = public_key.GetPublicKey()) {
                            // macOS behaviour is not consistent - but the test main goal is to check we get a key
                            Assert.That(pub.Handle, Is.Not.EqualTo(IntPtr.Zero), "public/GetPublicKey");
                        }
#else
                        Assert.True(public_key.IsAlgorithmSupported(SecKeyOperationType.Decrypt, SecKeyAlgorithm.RsaEncryptionPkcs1), "public/IsAlgorithmSupported/Decrypt");

                        using (var pub = public_key.GetPublicKey())
                        {
                            // a new native instance of the key is returned (so having a new managed SecKey is fine)
                            Assert.False(pub.Handle == public_key.Handle, "public/GetPublicKey");
                        }
#endif

                        using (var attrs = public_key.GetAttributes()) {
                            Assert.That(attrs.Count, Is.GreaterThan((nuint)0), "public/GetAttributes");
                        }
                        using (var data = public_key.GetExternalRepresentation(out error)) {
                            Assert.Null(error, "public/error-1");
                            Assert.NotNull(data, "public/GetExternalRepresentation");

                            using (var key = SecKey.Create(data, SecKeyType.RSA, SecKeyClass.Public, MinRsaKeySize, null, out error)) {
                                Assert.Null(error, "public/Create/error-1");
                            }
                        }
                    }
                    Assert.That(public_key.Encrypt(SecPadding.PKCS1, plain, out cipher), Is.EqualTo(SecStatusCode.Success), "Encrypt");

                    byte[] result;
                    if (TestRuntime.CheckXcodeVersion(8, 0))
                    {
                        Assert.False(private_key.IsAlgorithmSupported(SecKeyOperationType.Encrypt, SecKeyAlgorithm.RsaEncryptionPkcs1), "private/IsAlgorithmSupported/Encrypt");
                        Assert.True(private_key.IsAlgorithmSupported(SecKeyOperationType.Decrypt, SecKeyAlgorithm.RsaEncryptionPkcs1), "private/IsAlgorithmSupported/Decrypt");

                        using (var pub2 = private_key.GetPublicKey()) {
                            // a new native instance of the key is returned (so having a new managed SecKey is fine)
                            Assert.That(pub2.Handle, Is.Not.EqualTo(public_key.Handle), "private/GetPublicKey");
                        }

                        using (var attrs = private_key.GetAttributes()) {
                            Assert.That(attrs.Count, Is.GreaterThan((nuint)0), "private/GetAttributes");
                        }
                        using (var data2 = private_key.GetExternalRepresentation(out error)) {
                            Assert.Null(error, "private/error-1");
                            Assert.NotNull(data2, "private/GetExternalRepresentation");

                            using (var key = SecKey.Create(data2, SecKeyType.RSA, SecKeyClass.Private, MinRsaKeySize, null, out error)) {
                                Assert.Null(error, "private/Create/error-1");
                            }
                        }
                    }
                    public_key.Dispose();
                    var expectedResult = SecStatusCode.Success;
#if __MACOS__
                    if (!TestRuntime.CheckSystemVersion(PlatformName.MacOSX, 10, 8))
                    {
                        expectedResult = SecStatusCode.InvalidData;
                    }
#endif
                    Assert.That(private_key.Decrypt(SecPadding.PKCS1, cipher, out result), Is.EqualTo(expectedResult), "Decrypt");
                    if (expectedResult != SecStatusCode.InvalidData)
                    {
                        Assert.That(plain, Is.EqualTo(result), "match");
                    }
                    private_key.Dispose();
                }
            } finally {
                // Clean up after us
                DeleteKeysWithLabel(label);
            }
        }
Esempio n. 22
0
        protected INativeObject GetINativeInstance(Type t)
        {
            var ctor = t.GetConstructor(Type.EmptyTypes);

            if ((ctor != null) && !ctor.IsAbstract)
            {
                return(ctor.Invoke(null) as INativeObject);
            }

            if (!NativeObjectInterfaceType.IsAssignableFrom(t))
            {
                throw new ArgumentException("t");
            }
            switch (t.Name)
            {
            case "CFAllocator":
                return(CFAllocator.SystemDefault);

            case "CFBundle":
                var bundles = CFBundle.GetAll();
                if (bundles.Length > 0)
                {
                    return(bundles [0]);
                }
                else
                {
                    throw new InvalidOperationException(string.Format("Could not create the new instance for type {0}.", t.Name));
                }

            case "CFNotificationCenter":
                return(CFNotificationCenter.Darwin);

            case "CFReadStream":
            case "CFStream":
                CFReadStream  readStream;
                CFWriteStream writeStream;
                CFStream.CreatePairWithSocketToHost("www.google.com", 80, out readStream, out writeStream);
                return(readStream);

            case "CFWriteStream":
                CFStream.CreatePairWithSocketToHost("www.google.com", 80, out readStream, out writeStream);
                return(writeStream);

            case "CFUrl":
                return(CFUrl.FromFile("/etc"));

            case "CFPropertyList":
                return(CFPropertyList.FromData(NSData.FromString("<string>data</string>")).PropertyList);

            case "DispatchData":
                return(DispatchData.FromByteBuffer(new byte [] { 1, 2, 3, 4 }));

            case "AudioFile":
                var path = Path.GetFullPath("1.caf");
                var af   = AudioFile.Open(CFUrl.FromFile(path), AudioFilePermission.Read, AudioFileType.CAF);
                return(af);

            case "CFHTTPMessage":
                return(CFHTTPMessage.CreateEmpty(false));

            case "CFMutableString":
                return(new CFMutableString("xamarin"));

            case "CGBitmapContext":
                byte[] data = new byte [400];
                using (CGColorSpace space = CGColorSpace.CreateDeviceRGB()) {
                    return(new CGBitmapContext(data, 10, 10, 8, 40, space, CGBitmapFlags.PremultipliedLast));
                }

            case "CGContextPDF":
                var filename = Environment.GetFolderPath(Environment.SpecialFolder.CommonDocuments) + "/t.pdf";
                using (var url = new NSUrl(filename))
                    return(new CGContextPDF(url));

            case "CGColorConversionInfo":
                var cci = new GColorConversionInfoTriple()
                {
                    Space     = CGColorSpace.CreateGenericRgb(),
                    Intent    = CGColorRenderingIntent.Default,
                    Transform = CGColorConversionInfoTransformType.ApplySpace
                };
                return(new CGColorConversionInfo((NSDictionary)null, cci, cci, cci));

            case "CGDataConsumer":
                using (NSMutableData destData = new NSMutableData()) {
                    return(new CGDataConsumer(destData));
                }

            case "CGDataProvider":
                filename = "xamarin1.png";
                return(new CGDataProvider(filename));

            case "CGFont":
                return(CGFont.CreateWithFontName("Courier New"));

            case "CGPattern":
                return(new CGPattern(
                           new RectangleF(0, 0, 16, 16),
                           CGAffineTransform.MakeIdentity(),
                           16, 16,
                           CGPatternTiling.NoDistortion,
                           true,
                           (cgc) => {}));

            case "CMBufferQueue":
                return(CMBufferQueue.CreateUnsorted(2));

            case "CTFont":
                CTFontDescriptorAttributes fda = new CTFontDescriptorAttributes()
                {
                    FamilyName = "Courier",
                    StyleName  = "Bold",
                    Size       = 16.0f
                };
                using (var fd = new CTFontDescriptor(fda))
                    return(new CTFont(fd, 10));

            case "CTFontCollection":
                return(new CTFontCollection(new CTFontCollectionOptions()));

            case "CTFontDescriptor":
                fda = new CTFontDescriptorAttributes();
                return(new CTFontDescriptor(fda));

            case "CTTextTab":
                return(new CTTextTab(CTTextAlignment.Left, 2));

            case "CTTypesetter":
                return(new CTTypesetter(new NSAttributedString("Hello, world",
                                                               new CTStringAttributes()
                {
                    ForegroundColorFromContext = true,
                    Font = new CTFont("ArialMT", 24)
                })));

            case "CTFrame":
                var framesetter = new CTFramesetter(new NSAttributedString("Hello, world",
                                                                           new CTStringAttributes()
                {
                    ForegroundColorFromContext = true,
                    Font = new CTFont("ArialMT", 24)
                }));
                var bPath = UIBezierPath.FromRect(new RectangleF(0, 0, 3, 3));
                return(framesetter.GetFrame(new NSRange(0, 0), bPath.CGPath, null));

            case "CTFramesetter":
                return(new CTFramesetter(new NSAttributedString("Hello, world",
                                                                new CTStringAttributes()
                {
                    ForegroundColorFromContext = true,
                    Font = new CTFont("ArialMT", 24)
                })));

            case "CTGlyphInfo":
                return(new CTGlyphInfo("copyright", new CTFont("ArialMY", 24), "Foo"));

            case "CTLine":
                return(new CTLine(new NSAttributedString("Hello, world",
                                                         new CTStringAttributes()
                {
                    ForegroundColorFromContext = true,
                    Font = new CTFont("ArialMT", 24)
                })));

            case "CGImageDestination":
                var storage = new NSMutableData();
                return(CGImageDestination.Create(new CGDataConsumer(storage), "public.png", 1));

            case "CGImageMetadataTag":
                using (NSString name = new NSString("tagName"))
                    using (var value = new NSString("value"))
                        return(new CGImageMetadataTag(CGImageMetadataTagNamespaces.Exif, CGImageMetadataTagPrefixes.Exif, name, CGImageMetadataType.Default, value));

            case "CGImageSource":
                filename = "xamarin1.png";
                return(CGImageSource.FromUrl(NSUrl.FromFilename(filename)));

            case "SecPolicy":
                return(SecPolicy.CreateSslPolicy(false, null));

            case "SecIdentity":
                using (var options = NSDictionary.FromObjectAndKey(new NSString("farscape"), SecImportExport.Passphrase)) {
                    NSDictionary[] array;
                    var            result = SecImportExport.ImportPkcs12(farscape_pfx, options, out array);
                    if (result != SecStatusCode.Success)
                    {
                        throw new InvalidOperationException(string.Format("Could not create the new instance for type {0} due to {1}.", t.Name, result));
                    }
                    return(new SecIdentity(array [0].LowlevelObjectForKey(SecImportExport.Identity.Handle)));
                }

            case "SecTrust":
                X509Certificate x = new X509Certificate(mail_google_com);
                using (var policy = SecPolicy.CreateSslPolicy(true, "mail.google.com"))
                    return(new SecTrust(x, policy));

            case "SslContext":
                return(new SslContext(SslProtocolSide.Client, SslConnectionType.Stream));

            case "UIFontFeature":
                return(new UIFontFeature(CTFontFeatureNumberSpacing.Selector.ProportionalNumbers));

            case "NetworkReachability":
                return(new NetworkReachability(IPAddress.Loopback, null));

            case "VTCompressionSession":
            case "VTSession":
                return(VTCompressionSession.Create(1024, 768, CMVideoCodecType.H264, (sourceFrame, status, flags, buffer) => { }, null, (CVPixelBufferAttributes)null));

            case "VTFrameSilo":
                return(VTFrameSilo.Create());

            case "VTMultiPassStorage":
                return(VTMultiPassStorage.Create());

            case "CFString":
                return(new CFString("test"));

            case "DispatchBlock":
                return(new DispatchBlock(() => { }));

            case "DispatchQueue":
                return(new DispatchQueue("com.example.subsystem.taskXYZ"));

            case "DispatchGroup":
                return(DispatchGroup.Create());

            case "CGColorSpace":
                return(CGColorSpace.CreateDeviceCmyk());

            case "CGGradient":
                CGColor[] cArray = { UIColor.Black.CGColor, UIColor.Clear.CGColor, UIColor.Blue.CGColor };
                return(new CGGradient(null, cArray));

            case "CGImage":
                filename = "xamarin1.png";
                using (var dp = new CGDataProvider(filename))
                    return(CGImage.FromPNG(dp, null, false, CGColorRenderingIntent.Default));

            case "CGColor":
                return(UIColor.Black.CGColor);

            case "CMClock":
                return(CMClock.HostTimeClock);

            case "CMTimebase":
                return(new CMTimebase(CMClock.HostTimeClock));

            case "CVPixelBufferPool":
                return(new CVPixelBufferPool(
                           new CVPixelBufferPoolSettings(),
                           new CVPixelBufferAttributes(CVPixelFormatType.CV24RGB, 100, 50)
                           ));

            case "SecCertificate":
                using (var cdata = NSData.FromArray(mail_google_com))
                    return(new SecCertificate(cdata));

            case "SecCertificate2":
                using (var cdata = NSData.FromArray(mail_google_com))
                    return(new SecCertificate2(new SecCertificate(cdata)));

            case "SecTrust2":
                X509Certificate x2 = new X509Certificate(mail_google_com);
                using (var policy = SecPolicy.CreateSslPolicy(true, "mail.google.com"))
                    return(new SecTrust2(new SecTrust(x2, policy)));

            case "SecIdentity2":
                using (var options = NSDictionary.FromObjectAndKey(new NSString("farscape"), SecImportExport.Passphrase)) {
                    NSDictionary[] array;
                    var            result = SecImportExport.ImportPkcs12(farscape_pfx, options, out array);
                    if (result != SecStatusCode.Success)
                    {
                        throw new InvalidOperationException(string.Format("Could not create the new instance for type {0} due to {1}.", t.Name, result));
                    }
                    return(new SecIdentity2(new SecIdentity(array [0].LowlevelObjectForKey(SecImportExport.Identity.Handle))));
                }

            case "SecKey":
                SecKey private_key;
                SecKey public_key;
                using (var record = new SecRecord(SecKind.Key)) {
                    record.KeyType       = SecKeyType.RSA;
                    record.KeySizeInBits = 512;                     // it's not a performance test :)
                    SecKey.GenerateKeyPair(record.ToDictionary(), out public_key, out private_key);
                    return(private_key);
                }

            case "SecAccessControl":
                return(new SecAccessControl(SecAccessible.WhenPasscodeSetThisDeviceOnly));

            default:
                throw new InvalidOperationException(string.Format("Could not create the new instance for type {0}.", t.Name));
            }
        }
Esempio n. 23
0
        public void RoundtripRSA512PKCS1()
        {
            NSError error;
            SecKey  private_key;
            SecKey  public_key;

            using (var record = new SecRecord(SecKind.Key)) {
                record.KeyType       = SecKeyType.RSA;
                record.KeySizeInBits = 512;                 // it's not a performance test :)

                Assert.That(SecKey.GenerateKeyPair(record.ToDictionary(), out public_key, out private_key), Is.EqualTo(SecStatusCode.Success), "GenerateKeyPair");

                byte [] plain = new byte [20] {
                    1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
                };
                byte [] cipher;
                if (TestRuntime.CheckXcodeVersion(8, 0))
                {
                    Assert.True(public_key.IsAlgorithmSupported(SecKeyOperationType.Encrypt, SecKeyAlgorithm.RsaEncryptionPkcs1), "public/IsAlgorithmSupported/Encrypt");
                    // I would have expect false
                    Assert.True(public_key.IsAlgorithmSupported(SecKeyOperationType.Decrypt, SecKeyAlgorithm.RsaEncryptionPkcs1), "public/IsAlgorithmSupported/Decrypt");

                    using (var pub = public_key.GetPublicKey()) {
                        // a new native instance of the key is returned (so having a new managed SecKey is fine)
                        Assert.That(pub.Handle, Is.Not.EqualTo(public_key.Handle), "public/GetPublicKey");
                    }
                    using (var attrs = public_key.GetAttributes()) {
                        Assert.That(attrs.Count, Is.GreaterThan(0), "public/GetAttributes");
                    }
                    using (var data = public_key.GetExternalRepresentation(out error)) {
                        Assert.Null(error, "public/error-1");
                        Assert.NotNull(data, "public/GetExternalRepresentation");

                        using (var key = SecKey.Create(data, SecKeyType.RSA, SecKeyClass.Public, 512, null, out error)) {
                            Assert.Null(error, "public/Create/error-1");
                        }
                    }
                }
                Assert.That(public_key.Encrypt(SecPadding.PKCS1, plain, out cipher), Is.EqualTo(SecStatusCode.Success), "Encrypt");

                byte[] result;
                if (TestRuntime.CheckXcodeVersion(8, 0))
                {
                    Assert.False(private_key.IsAlgorithmSupported(SecKeyOperationType.Encrypt, SecKeyAlgorithm.RsaEncryptionPkcs1), "private/IsAlgorithmSupported/Encrypt");
                    Assert.True(private_key.IsAlgorithmSupported(SecKeyOperationType.Decrypt, SecKeyAlgorithm.RsaEncryptionPkcs1), "private/IsAlgorithmSupported/Decrypt");

                    using (var pub2 = private_key.GetPublicKey()) {
                        // a new native instance of the key is returned (so having a new managed SecKey is fine)
                        Assert.That(pub2.Handle, Is.Not.EqualTo(public_key.Handle), "private/GetPublicKey");
                    }
                    using (var attrs = private_key.GetAttributes()) {
                        Assert.That(attrs.Count, Is.GreaterThan(0), "private/GetAttributes");
                    }
                    using (var data2 = private_key.GetExternalRepresentation(out error)) {
                        Assert.Null(error, "private/error-1");
                        Assert.NotNull(data2, "private/GetExternalRepresentation");

                        using (var key = SecKey.Create(data2, SecKeyType.RSA, SecKeyClass.Private, 512, null, out error)) {
                            Assert.Null(error, "private/Create/error-1");
                        }
                    }
                }
                public_key.Dispose();
                Assert.That(private_key.Decrypt(SecPadding.PKCS1, cipher, out result), Is.EqualTo(SecStatusCode.Success), "Decrypt");
                Assert.That(plain, Is.EqualTo(result), "match");
                private_key.Dispose();
            }
        }
        protected INativeObject GetINativeInstance(Type t)
        {
            var ctor = t.GetConstructor (Type.EmptyTypes);
            if ((ctor != null) && !ctor.IsAbstract)
                return ctor.Invoke (null) as INativeObject;

            if (!NativeObjectInterfaceType.IsAssignableFrom (t))
                throw new ArgumentException ("t");
            switch (t.Name) {
            case "CFAllocator":
                return CFAllocator.SystemDefault;
            case "CFBundle":
                var bundles = CFBundle.GetAll ();
                if (bundles.Length > 0)
                    return bundles [0];
                else
                    throw new InvalidOperationException (string.Format ("Could not create the new instance for type {0}.", t.Name));
            case "CFNotificationCenter":
                return CFNotificationCenter.Darwin;
            case "CFReadStream":
            case "CFStream":
                CFReadStream readStream;
                CFWriteStream writeStream;
                CFStream.CreatePairWithSocketToHost ("www.google.com", 80, out readStream, out writeStream);
                return readStream;
            case "CFWriteStream":
                CFStream.CreatePairWithSocketToHost ("www.google.com", 80, out readStream, out writeStream);
                return writeStream;
            case "CFUrl":
                return CFUrl.FromFile ("/etc");
            case "AudioFile":
                var path = Path.GetFullPath ("1.caf");
                var af = AudioFile.Open (CFUrl.FromFile (path), AudioFilePermission.Read, AudioFileType.CAF);
                return af;
            case "CFHTTPMessage":
                return CFHTTPMessage.CreateEmpty (false);
            case "CGBitmapContext":
                byte[] data = new byte [400];
                using (CGColorSpace space = CGColorSpace.CreateDeviceRGB ()) {
                    return new CGBitmapContext (data, 10, 10, 8, 40, space, CGBitmapFlags.PremultipliedLast);
                }
            case "CGContextPDF":
                var filename = Environment.GetFolderPath (Environment.SpecialFolder.CommonDocuments) + "/t.pdf";
                using (var url = new NSUrl (filename))
                    return new CGContextPDF (url);
            case "CGColorConverter":
                var cvt = new CGColorConverterTriple () {
                    Space = CGColorSpace.CreateGenericRgb (),
                    Intent = CGColorRenderingIntent.Default,
                    Transform = CGColorConverterTransformType.ApplySpace
                };
                return new CGColorConverter (null, cvt, cvt, cvt);
            case "CGDataConsumer":
                using (NSMutableData destData = new NSMutableData ()) {
                    return new CGDataConsumer (destData);
                }
            case "CGDataProvider":
                filename = "xamarin1.png";
                return new CGDataProvider (filename);
            case "CGFont":
                return CGFont.CreateWithFontName ("Courier New");
            case "CGPattern":
                return new CGPattern (
                    new RectangleF (0, 0, 16, 16),
                    CGAffineTransform.MakeIdentity (),
                    16, 16,
                    CGPatternTiling.NoDistortion,
                    true,
                    (cgc) => {});
            case "CMBufferQueue":
                return CMBufferQueue.CreateUnsorted (2);
            case "CTFont":
                CTFontDescriptorAttributes fda = new CTFontDescriptorAttributes () {
                    FamilyName = "Courier",
                    StyleName = "Bold",
                    Size = 16.0f
                };
                using (var fd = new CTFontDescriptor (fda))
                    return new CTFont (fd, 10, CTFontOptions.Default);
            case "CTFontCollection":
                return new CTFontCollection (new CTFontCollectionOptions ());
            case "CTFontDescriptor":
                fda = new CTFontDescriptorAttributes ();
                return new CTFontDescriptor (fda);
            case "CTTextTab":
                return new CTTextTab (CTTextAlignment.Left, 2);
            case "CTTypesetter":
                return new CTTypesetter (new NSAttributedString ("Hello, world",
                    new CTStringAttributes () {
                        ForegroundColorFromContext =  true,
                        Font = new CTFont ("Arial", 24)
                    }));
            case "CTFrame":
                var framesetter = new CTFramesetter (new NSAttributedString ("Hello, world",
                    new CTStringAttributes () {
                        ForegroundColorFromContext =  true,
                        Font = new CTFont ("Arial", 24)
                    }));
                var bPath = UIBezierPath.FromRect (new RectangleF (0, 0, 3, 3));
                return framesetter.GetFrame (new NSRange (0, 0), bPath.CGPath, null);
            case "CTFramesetter":
                return new CTFramesetter (new NSAttributedString ("Hello, world",
                    new CTStringAttributes () {
                        ForegroundColorFromContext =  true,
                        Font = new CTFont ("Arial", 24)
                    }));
            case "CTGlyphInfo":
                return new CTGlyphInfo ("Zapfino", new CTFont ("Arial", 24), "Foo");
            case "CTLine":
                return new CTLine (new NSAttributedString ("Hello, world",
                    new CTStringAttributes () {
                        ForegroundColorFromContext =  true,
                        Font = new CTFont ("Arial", 24)
                    }));
            case "CGImageDestination":
                var storage = new NSMutableData ();
                return CGImageDestination.Create (new CGDataConsumer (storage), "public.png", 1);
            case "CGImageMetadataTag":
                using (NSString name = new NSString ("tagName"))
                using (var value = new NSString ("value"))
                    return new CGImageMetadataTag (CGImageMetadataTagNamespaces.Exif, CGImageMetadataTagPrefixes.Exif, name, CGImageMetadataType.Default, value);
            case "CGImageSource":
                filename = "xamarin1.png";
                return CGImageSource.FromUrl (NSUrl.FromFilename (filename));
            case "SecPolicy":
                return SecPolicy.CreateSslPolicy (false, null);
            case "SecIdentity":
                using (var options = NSDictionary.FromObjectAndKey (new NSString ("farscape"), SecImportExport.Passphrase)) {
                    NSDictionary[] array;
                    var result = SecImportExport.ImportPkcs12 (farscape_pfx, options, out array);
                    if (result != SecStatusCode.Success)
                        throw new InvalidOperationException (string.Format ("Could not create the new instance for type {0} due to {1}.", t.Name, result));
                    return new SecIdentity (array [0].LowlevelObjectForKey (SecImportExport.Identity.Handle));
                }
            case "SecTrust":
                X509Certificate x = new X509Certificate (mail_google_com);
                using (var policy = SecPolicy.CreateSslPolicy (true, "mail.google.com"))
                    return new SecTrust (x, policy);
            case "SslContext":
                return new SslContext (SslProtocolSide.Client, SslConnectionType.Stream);
            case "UIFontFeature":
                return new UIFontFeature (CTFontFeatureNumberSpacing.Selector.ProportionalNumbers);
            case "NetworkReachability":
                return new NetworkReachability (IPAddress.Loopback, null);
            #if !__TVOS__
            case "VTCompressionSession":
            case "VTSession":
                return VTCompressionSession.Create (1024, 768, CMVideoCodecType.H264, (sourceFrame, status, flags, buffer) => { }, null, (CVPixelBufferAttributes) null);
            case "VTFrameSilo":
                return VTFrameSilo.Create ();
            case "VTMultiPassStorage":
                return VTMultiPassStorage.Create ();
            #endif
            case "CFString":
                return new CFString ("test");
            case "DispatchQueue":
                return new DispatchQueue ("com.example.subsystem.taskXYZ");
            case "DispatchGroup":
                return DispatchGroup.Create ();
            case "CGColorSpace":
                return CGColorSpace.CreateAcesCGLinear ();
            case "CGGradient":
                CGColor[] cArray = { UIColor.Black.CGColor, UIColor.Clear.CGColor, UIColor.Blue.CGColor };
                return new CGGradient (null, cArray);
            case "CGImage":
                filename = "xamarin1.png";
                using (var dp = new CGDataProvider (filename))
                    return CGImage.FromPNG (dp, null, false, CGColorRenderingIntent.Default);
            case "CGColor":
                return UIColor.Black.CGColor;
            case "CMClock":
                CMClockError ce;
                CMClock clock = CMClock.CreateAudioClock (out ce);
                if (ce == CMClockError.None)
                    return clock;
                throw new InvalidOperationException (string.Format ("Could not create the new instance for type {0}.", t.Name));
            case "CMTimebase":
                clock = CMClock.CreateAudioClock (out ce);
                if (ce == CMClockError.None) {
                    return new CMTimebase (clock);
                }
                throw new InvalidOperationException (string.Format ("Could not create the new instance for type {0}.", t.Name));
            case "CVPixelBufferPool":
                return new CVPixelBufferPool (
                    new CVPixelBufferPoolSettings (),
                    new CVPixelBufferAttributes (CVPixelFormatType.CV24RGB, 100, 50)
                );
            case "SecCertificate":
                using (var cdata = NSData.FromArray (mail_google_com))
                    return new SecCertificate (cdata);
            case "SecKey":
                SecKey private_key;
                SecKey public_key;
                using (var record = new SecRecord (SecKind.Key)) {
                    record.KeyType = SecKeyType.RSA;
                    record.KeySizeInBits = 512; // it's not a performance test :)
                    SecKey.GenerateKeyPair (record.ToDictionary (), out public_key, out private_key);
                    return private_key;
                }
            case "SecAccessControl":
                return new SecAccessControl (SecAccessible.WhenPasscodeSetThisDeviceOnly);
            default:
                throw new InvalidOperationException (string.Format ("Could not create the new instance for type {0}.", t.Name));
            }
        }