예제 #1
0
        public void InstallCertificate(string certificate)
        {
            if (certificate.StartsWith("http", StringComparison.CurrentCulture))
            {
                OpenUrlExternally(certificate);
            }

            //THIS CASE DOESN"T WORK YET, WE CAN ONLY ADD THE CERT TO THE KEYCHAIN BUT NOT PROMPT FOR TRUST
            else
            {
                NSData certData = NSData.FromUrl(new NSUrl(certificate));

                SecCertificate secCertificate = new SecCertificate(certData);

                SecRecord secRecord = new SecRecord(SecKind.Certificate);

                secRecord.SetValueRef(secCertificate);


                SecPolicy policy   = SecPolicy.CreateSslPolicy(true, "applocker.navy.mil");
                SecTrust  secTrust = new SecTrust(secCertificate, policy);
                //SecTrustResult results = secTrust.GetTrustResult();

                SecStatusCode code = SecKeyChain.Add(secRecord);
                Console.WriteLine(code);
            }
        }
예제 #2
0
        public void AddQueryRemove_Identity()
        {
            using (SecRecord rec = new SecRecord(SecKind.Identity))
                using (var id = IdentityTest.GetIdentity()) {
                    rec.SetValueRef(id);
                    SecStatusCode code = SecKeyChain.Add(rec);
                    Assert.True(code == SecStatusCode.DuplicateItem || code == SecStatusCode.Success);
                }

            if (!TestRuntime.CheckXcodeVersion(5, 0))
            {
                Assert.Inconclusive("QueryAsConcreteType does not work before iOS7");
            }

            using (SecRecord rec = new SecRecord(SecKind.Identity)) {
                SecStatusCode code;
                var           match = SecKeyChain.QueryAsConcreteType(rec, out code);
                if ((match == null) && (code == SecStatusCode.ItemNotFound))
                {
                    Assert.Inconclusive("Test randomly fails (race condition between addtion/commit/query?");
                }

                Assert.That(code, Is.EqualTo(SecStatusCode.Success), "QueryAsRecord-2");
                Assert.NotNull(match, "match-2");

                code = SecKeyChain.Remove(rec);
                Assert.That(code, Is.EqualTo(SecStatusCode.Success), "Remove");

                match = SecKeyChain.QueryAsConcreteType(rec, out code);
                Assert.That(code, Is.EqualTo(SecStatusCode.ItemNotFound), "QueryAsRecord-3");
                Assert.Null(match, "match-3");
            }
        }
예제 #3
0
        public void Add_Certificate()
        {
            Stream certStream = typeof(KeyChainTest).Assembly.GetManifestResourceStream("monotouchtest.Security.openssl_crt.der");
            NSData data       = NSData.FromStream(certStream);

            var rec = new SecRecord(SecKind.Certificate)
            {
                Label = "MyCert"
            };

            rec.SetValueRef(new SecCertificate(data));

            var rc = SecKeyChain.Add(rec);

            Assert.IsTrue(rc == SecStatusCode.Success || rc == SecStatusCode.DuplicateItem, "Add_Certificate");
        }
예제 #4
0
        //
        // EXPERIMENTAL
        // Needs some more testing before we can make this public.
        // AppleTls does not actually use this API, so it may be removed again.
        //
        internal NSData GetPublicKey()
        {
            if (handle == IntPtr.Zero)
            {
                throw new ObjectDisposedException("SecCertificate");
            }

            var policy = SecPolicy.CreateBasicX509Policy();
            var trust  = new SecTrust(this, policy);

            trust.Evaluate();

            SecStatusCode status;

            using (var key = trust.GetPublicKey())
                using (var query = new SecRecord(SecKind.Key)) {
                    query.SetValueRef(key);

                    status = SecKeyChain.Add(query);
                    if (status != SecStatusCode.Success && status != SecStatusCode.DuplicateItem)
                    {
                        throw new InvalidOperationException(status.ToString());
                    }

                    bool added = status == SecStatusCode.Success;

                    try {
                        var data = SecKeyChain.QueryAsData(query, false, out status);
                        if (status != SecStatusCode.Success)
                        {
                            throw new InvalidOperationException(status.ToString());
                        }

                        return(data);
                    } finally {
                        if (added)
                        {
                            status = SecKeyChain.Remove(query);
                            if (status != SecStatusCode.Success)
                            {
                                throw new InvalidOperationException(status.ToString());
                            }
                        }
                    }
                }
        }
예제 #5
0
        public void Add_Certificate()
        {
#if MONOMAC
            Stream certStream = typeof(KeyChainTest).Assembly.GetManifestResourceStream("xammac_tests.Security.openssl_crt.der");
#else
            Stream certStream = typeof(KeyChainTest).Assembly.GetManifestResourceStream("monotouchtest.Security.openssl_crt.der");
#endif
            NSData data = NSData.FromStream(certStream);

            var rec = new SecRecord(SecKind.Certificate)
            {
                Label = "MyCert"
            };
            rec.SetValueRef(new SecCertificate(data));

            var rc = SecKeyChain.Add(rec);
            Assert.That(rc, Is.EqualTo(SecStatusCode.Success).Or.EqualTo(SecStatusCode.DuplicateItem), "Add_Certificate");
        }
예제 #6
0
		//
		// EXPERIMENTAL
		// Needs some more testing before we can make this public.
		// AppleTls does not actually use this API, so it may be removed again.
		//
		internal NSData GetPublicKey ()
		{
			if (handle == IntPtr.Zero)
				throw new ObjectDisposedException ("SecCertificate");

			var policy = SecPolicy.CreateBasicX509Policy ();
			var trust = new SecTrust (this, policy);
			trust.Evaluate ();

			SecStatusCode status;

			using (var key = trust.GetPublicKey ())
			using (var query = new SecRecord (SecKind.Key)) {
				query.SetValueRef (key);

				status = SecKeyChain.Add (query);
				if (status != SecStatusCode.Success && status != SecStatusCode.DuplicateItem)
					throw new InvalidOperationException (status.ToString ());

				bool added = status == SecStatusCode.Success;

				try {
					var data = SecKeyChain.QueryAsData (query, false, out status);
					if (status != SecStatusCode.Success)
						throw new InvalidOperationException (status.ToString ());

					return data;
				} finally {
					if (added) {
						status = SecKeyChain.Remove (query);
						if (status != SecStatusCode.Success)
							throw new InvalidOperationException (status.ToString ());
					}
				}
			}
		}
        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);
                }
            }
        }