public static void DisplayX509Certificate2 (NSObject sender, X509Certificate2 cert)
        {
            Class sfCertificatePanelClass = new Class ("SFCertificatePanel");
            Selector sharedCertificatePanelSelector = new Selector ("sharedCertificatePanel");

            // + (SFCertificatePanel *)sharedCertificatePanel;
            IntPtr panel = IntPtr_objc_msgSend (sfCertificatePanelClass.Handle, sharedCertificatePanelSelector.Handle);

            using (var sc = new SecCertificate (cert)) {
                NSArray a = NSArray.FromNSObjects (sc);

                //- (NSInteger)runModalForCertificates:(NSArray *)certificates showGroup:(BOOL)showGroup;
                //nint_objc_msgSend_IntPtr_bool (panel, Selector.GetHandle ("runModalForCertificates:showGroup:"), a.Handle, false);

                // - (void)beginSheetForWindow:(NSWindow *)docWindow modalDelegate:(id)delegate didEndSelector:(SEL)didEndSelector contextInfo:(void *)contextInfo certificates:(NSArray *)certificates showGroup:(BOOL)showGroup;
                void_objc_msgSend_IntPtr_IntPtr_IntPtr_IntPtr_bool (panel, Selector.GetHandle ("beginSheetForWindow:modalDelegate:didEndSelector:contextInfo:certificates:showGroup:"), 
                    NSApplication.SharedApplication.MainWindow.Handle, sender.Handle, Selector.GetHandle ("createPanelDidEnd:returnCode:contextInfo:"), IntPtr.Zero, a.Handle, false);
            }
        }
Esempio n. 2
0
        public static SecIdentity GetIdentity(X509Certificate certificate)
        {
            /*
             * If we got an 'X509Certificate2', then we require it to have a private key
             * and import it.
             */
            var certificate2 = certificate as X509Certificate2;

            if (certificate2 != null)
            {
                return(SecIdentity.Import(certificate2));
            }

            /*
             * Otherwise, we require the private key to be in the keychain.
             */
            using (var secCert = new SecCertificate(certificate)) {
                return(SecKeyChain.FindIdentity(secCert, true));
            }
        }
Esempio n. 3
0
        public void MailX1()
        {
            using (var cert = new X509Certificate(mail_google_com)) {
                /*
                 * This X509Certificate constructor will use SecCertificateCreateWithData() and
                 * store the SecCertificateRef in its Handle.
                 */
                Assert.That(cert.Handle, Is.Not.EqualTo(IntPtr.Zero), "Handle");
                Assert.That(CFGetRetainCount(cert.Handle), Is.EqualTo((nint)1), "RetainCount");
                using (var sc = new SecCertificate(cert)) {
#if NET
                    // dotnet PAL layer does not return the same instance
                    CheckMailGoogleCom(sc, 1);                      // so the new one is RC == 1
#else
                    Assert.That(sc.Handle, Is.EqualTo(cert.Handle), "Same Handle");
                    CheckMailGoogleCom(sc, 2);                      // same handle means another reference was added
#endif
                    Assert.That(cert.ToString(true), Is.EqualTo(sc.ToX509Certificate().ToString(true)), "X509Certificate");
                }
            }
        }
Esempio n. 4
0
        public void Trust_FullChain()
        {
            X509CertificateCollection certs = new X509CertificateCollection();

            certs.Add(new X509Certificate(CertificateTest.mail_google_com));
            certs.Add(new X509Certificate(CertificateTest.thawte_sgc_ca));
            certs.Add(new X509Certificate(CertificateTest.verisign_class3_root));
            using (var policy = SecPolicy.CreateSslPolicy(true, "mail.google.com"))
                using (var trust = new SecTrust(certs, policy)) {
                    // that certificate stopped being valid on September 30th, 2013 so we validate it with a date earlier than that
                    trust.SetVerifyDate(new DateTime(635108745218945450, DateTimeKind.Utc));

                    SecTrustResult trust_result = SecTrustResult.Unspecified;
                    var            ios9         = TestRuntime.CheckXcodeVersion(7, 0);
                    var            ios10        = TestRuntime.CheckXcodeVersion(8, 0);
                    var            ios11        = TestRuntime.CheckXcodeVersion(9, 0);
                    if (ios10)
                    {
                        trust_result = SecTrustResult.FatalTrustFailure;
                    }
                    // iOS9 is not fully happy with the basic constraints: `SecTrustEvaluate  [root AnchorTrusted BasicContraints]`
                    else if (ios9)
                    {
                        trust_result = SecTrustResult.RecoverableTrustFailure;
                    }
                    var result = Evaluate(trust, true);
                    Assert.That(result, Is.EqualTo(trust_result), "Evaluate");

                    // Evalute must be called prior to Count (Apple documentation)
                    Assert.That(trust.Count, Is.EqualTo(3), "Count");

                    using (SecCertificate sc1 = trust [0]) {
                        // seems the leaf gets an extra one
                        Assert.That(CFGetRetainCount(sc1.Handle), Is.GreaterThanOrEqualTo((nint)2), "RetainCount(sc1)");
                        Assert.That(sc1.SubjectSummary, Is.EqualTo("mail.google.com"), "SubjectSummary(sc1)");
                    }
                    using (SecCertificate sc2 = trust [1]) {
                        Assert.That(CFGetRetainCount(sc2.Handle), Is.GreaterThanOrEqualTo((nint)2), "RetainCount(sc2)");
                        Assert.That(sc2.SubjectSummary, Is.EqualTo("Thawte SGC CA"), "SubjectSummary(sc2)");
                    }
                    using (SecCertificate sc3 = trust [2]) {
                        Assert.That(CFGetRetainCount(sc3.Handle), Is.GreaterThanOrEqualTo((nint)2), "RetainCount(sc3)");
                        Assert.That(sc3.SubjectSummary, Is.EqualTo("Class 3 Public Primary Certification Authority"), "SubjectSummary(sc3)");
                    }

                    if (TestRuntime.CheckXcodeVersion(5, 0))
                    {
                        Assert.That(trust.GetTrustResult(), Is.EqualTo(trust_result), "GetTrustResult");

                        trust.SetAnchorCertificates(certs);
                        Assert.That(trust.GetCustomAnchorCertificates().Length, Is.EqualTo(certs.Count), "GetCustomAnchorCertificates");

                        if (ios11)
                        {
                            trust_result = SecTrustResult.Unspecified;
                        }
                        else
                        {
                            trust_result = SecTrustResult.Invalid;
                        }

                        // since we modified the `trust` instance it's result was invalidated (marked as unspecified on iOS 11)
                        Assert.That(trust.GetTrustResult(), Is.EqualTo(trust_result), "GetTrustResult-2");
                    }
                }
        }
Esempio n. 5
0
 public void MailRaw()
 {
     using (var sc = new SecCertificate(mail_google_com)) {
         CheckMailGoogleCom(sc, 1);
     }
 }
Esempio n. 6
0
 public X509Certificate GetAppleCertificate(X509Certificate certificate)
 {
     // This will remove the private key if we have any.
     using (var appleCert = new SecCertificate(certificate))
         return(appleCert.ToX509Certificate());
 }
Esempio n. 7
0
        void Trust_FullChain(SecTrust trust, SecPolicy policy, X509CertificateCollection certs)
        {
            // that certificate stopped being valid on September 30th, 2013 so we validate it with a date earlier than that
            trust.SetVerifyDate(new DateTime(635108745218945450, DateTimeKind.Utc));

            SecTrustResult trust_result = SecTrustResult.Unspecified;
            var            ios9         = TestRuntime.CheckXcodeVersion(7, 0);
            var            ios10        = TestRuntime.CheckXcodeVersion(8, 0);
            var            ios11        = TestRuntime.CheckXcodeVersion(9, 0);
            var            ios13        = TestRuntime.CheckXcodeVersion(11, 0);

            if (ios10)
            {
                trust_result = SecTrustResult.FatalTrustFailure;
            }
            // iOS9 is not fully happy with the basic constraints: `SecTrustEvaluate  [root AnchorTrusted BasicContraints]`
            else if (ios9)
            {
                trust_result = SecTrustResult.RecoverableTrustFailure;
            }
            var result = Evaluate(trust, true);

            Assert.That(result, Is.EqualTo(trust_result), "Evaluate");

            // Evalute must be called prior to Count (Apple documentation)
            Assert.That(trust.Count, Is.EqualTo(3), "Count");

            using (SecCertificate sc1 = trust [0]) {
                // seems the leaf gets an extra one
                Assert.That(CFGetRetainCount(sc1.Handle), Is.GreaterThanOrEqualTo((nint)2), "RetainCount(sc1)");
                Assert.That(sc1.SubjectSummary, Is.EqualTo("mail.google.com"), "SubjectSummary(sc1)");
            }
            using (SecCertificate sc2 = trust [1]) {
                Assert.That(CFGetRetainCount(sc2.Handle), Is.GreaterThanOrEqualTo((nint)2), "RetainCount(sc2)");
                Assert.That(sc2.SubjectSummary, Is.EqualTo("Thawte SGC CA"), "SubjectSummary(sc2)");
            }
            using (SecCertificate sc3 = trust [2]) {
                Assert.That(CFGetRetainCount(sc3.Handle), Is.GreaterThanOrEqualTo((nint)2), "RetainCount(sc3)");
                Assert.That(sc3.SubjectSummary, Is.EqualTo("Class 3 Public Primary Certification Authority"), "SubjectSummary(sc3)");
            }

            if (TestRuntime.CheckXcodeVersion(5, 0))
            {
                Assert.That(trust.GetTrustResult(), Is.EqualTo(trust_result), "GetTrustResult");

                trust.SetAnchorCertificates(certs);
                Assert.That(trust.GetCustomAnchorCertificates().Length, Is.EqualTo(certs.Count), "GetCustomAnchorCertificates");

#if __MACOS__
                if (TestRuntime.CheckSystemVersion(PlatformName.MacOSX, 10, 15))
                {
                    trust_result = SecTrustResult.RecoverableTrustFailure;
                }
                else if (TestRuntime.CheckSystemVersion(PlatformName.MacOSX, 10, 13))
                {
                    trust_result = SecTrustResult.Unspecified;
                }
                else if (TestRuntime.CheckSystemVersion(PlatformName.MacOSX, 10, 12))
                {
                    trust_result = SecTrustResult.Invalid;
                }
                else if (TestRuntime.CheckSystemVersion(PlatformName.MacOSX, 10, 11))
                {
                    trust_result = SecTrustResult.RecoverableTrustFailure;
                }
                else
                {
                    trust_result = SecTrustResult.Unspecified;
                }
#else
                if (ios13)
                {
                    trust_result = SecTrustResult.RecoverableTrustFailure;
                }
                else if (ios11)
                {
                    trust_result = SecTrustResult.Unspecified;
                }
                else
                {
                    trust_result = SecTrustResult.Invalid;
                }
#endif

                // since we modified the `trust` instance it's result was invalidated (marked as unspecified on iOS 11)
                Assert.That(trust.GetTrustResult(), Is.EqualTo(trust_result), "GetTrustResult-2");
            }
            if (TestRuntime.CheckXcodeVersion(12, 0))
            {
                // old certificate (built in our tests) was not quite up to spec and it eventually became important
                Assert.False(trust.Evaluate(out var error), "Evaluate");
                Assert.NotNull(error, "error");
                Assert.That(error.LocalizedDescription, Is.EqualTo("“mail.google.com” certificate is not standards compliant"), "desc");
            }
            else if (TestRuntime.CheckXcodeVersion(11, 0))
            {
                Assert.False(trust.Evaluate(out var error), "Evaluate");
                Assert.NotNull(error, "error");
                Assert.That(error.LocalizedDescription, Does.Contain("\"mail.google.com\",\"Thawte SGC CA\",\"Class 3 Public Primary Certification Authority\" certificates do not meet pinning requirements"));
                var underlyingError = (NSError)error.UserInfo [NSError.UnderlyingErrorKey];
                // Error is:
                // Certificate 0 “mail.google.com” has errors: Key size is not permitted for this use, SSL hostname does not match name(s) in certificate, Signature hash algorithm is not permitted for this use;Certificate 1 “Thawte SGC CA” has errors: Key size is not permitted for this use, Signature hash algorithm is not permitted for this use;Certificate 2 “Class 3 Public Primary Certification Authority” has errors: Key size is not permitted for this use;
                // But the exact format can vary
                // watchOS reports this:
                // Certificate 0 “mail.google.com” has errors: Key size is not permitted for this use, Signature hash algorithm is not permitted for this use, SSL hostname does not match name(s) in certificate;Certificate 1 “Thawte SGC CA” has errors: Key size is not permitted for this use, Signature hash algorithm is not permitted for this use;Certificate 2 “Class 3 Public Primary Certification Authority” has errors: Key size is not permitted for this use;
                Assert.That(underlyingError.LocalizedDescription, Does.Contain("Certificate 0 “mail.google.com” has errors: "));
                Assert.That(underlyingError.LocalizedDescription, Does.Contain("Key size is not permitted for this use"));
                Assert.That(underlyingError.LocalizedDescription, Does.Contain("SSL hostname does not match name(s) in certificate").Or.Contain("Signature hash algorithm is not permitted for this use"));
                Assert.That(underlyingError.LocalizedDescription, Does.Contain("Certificate 1 “Thawte SGC CA” has errors: Key size is not permitted for this use"));
                Assert.That(underlyingError.LocalizedDescription, Does.Contain("Certificate 2 “Class 3 Public Primary Certification Authority” has errors:"));
            }
            else if (TestRuntime.CheckXcodeVersion(10, 0))
            {
                Assert.True(trust.Evaluate(out var error), "Evaluate");
                Assert.Null(error, "error");
            }
        }
Esempio n. 8
0
            public override void DidReceiveChallenge(NSUrlSession session, NSUrlSessionTask task, NSUrlAuthenticationChallenge challenge, Action <NSUrlSessionAuthChallengeDisposition, NSUrlCredential> completionHandler)
            {
                if (challenge.ProtectionSpace.AuthenticationMethod == NSUrlProtectionSpace.AuthenticationMethodNTLM)
                {
                    NetworkCredential credentialsToUse;

                    if (This.Credentials != null)
                    {
                        if (This.Credentials is NetworkCredential)
                        {
                            credentialsToUse = (NetworkCredential)This.Credentials;
                        }
                        else
                        {
                            var uri = this.getResponseForTask(task).Request.RequestUri;
                            credentialsToUse = This.Credentials.GetCredential(uri, "NTLM");
                        }
                        var credential = new NSUrlCredential(credentialsToUse.UserName, credentialsToUse.Password, NSUrlCredentialPersistence.ForSession);
                        completionHandler(NSUrlSessionAuthChallengeDisposition.UseCredential, credential);
                    }
                    return;
                }

                if (challenge.ProtectionSpace.AuthenticationMethod == NSUrlProtectionSpace.AuthenticationMethodClientCertificate)
                {
                    Console.WriteLine("Client Cert!");

                    var password = "******";
                    var options  = NSDictionary.FromObjectAndKey(NSObject.FromObject(password), SecImportExport.Passphrase);

                    var path     = Path.Combine(NSBundle.MainBundle.BundlePath, "Content", "client.p12");
                    var certData = File.ReadAllBytes(path);

                    NSDictionary[] importResult;

                    X509Certificate cert = new X509Certificate(certData, password);

                    SecStatusCode statusCode     = SecImportExport.ImportPkcs12(certData, options, out importResult);
                    var           identityHandle = importResult[0][SecImportExport.Identity];
                    var           identity       = new SecIdentity(identityHandle.Handle);
                    var           certificate    = new SecCertificate(cert.GetRawCertData());

                    SecCertificate[] certificates = { certificate };
                    NSUrlCredential  credential   = NSUrlCredential.FromIdentityCertificatesPersistance(identity, certificates, NSUrlCredentialPersistence.ForSession);
                    completionHandler(NSUrlSessionAuthChallengeDisposition.UseCredential, credential);

                    return;
                }

                if (!This.customSSLVerification)
                {
                    goto doDefault;
                }

                if (challenge.ProtectionSpace.AuthenticationMethod != "NSURLAuthenticationMethodServerTrust")
                {
                    goto doDefault;
                }

                if (ServicePointManager.ServerCertificateValidationCallback == null)
                {
                    goto doDefault;
                }

                // Convert Mono Certificates to .NET certificates and build cert
                // chain from root certificate
                var serverCertChain   = challenge.ProtectionSpace.ServerSecTrust;
                var chain             = new X509Chain();
                X509Certificate2 root = null;
                var errors            = SslPolicyErrors.None;

                if (serverCertChain == null || serverCertChain.Count == 0)
                {
                    errors = SslPolicyErrors.RemoteCertificateNotAvailable;
                    goto sslErrorVerify;
                }

                if (serverCertChain.Count == 1)
                {
                    errors = SslPolicyErrors.RemoteCertificateChainErrors;
                    goto sslErrorVerify;
                }

                var netCerts = Enumerable.Range(0, serverCertChain.Count)
                               .Select(x => serverCertChain[x].ToX509Certificate2())
                               .ToArray();

                for (int i = 1; i < netCerts.Length; i++)
                {
                    chain.ChainPolicy.ExtraStore.Add(netCerts[i]);
                }

                root = netCerts[0];

                chain.ChainPolicy.RevocationFlag      = X509RevocationFlag.EntireChain;
                chain.ChainPolicy.RevocationMode      = X509RevocationMode.NoCheck;
                chain.ChainPolicy.UrlRetrievalTimeout = new TimeSpan(0, 1, 0);
                chain.ChainPolicy.VerificationFlags   = X509VerificationFlags.AllowUnknownCertificateAuthority;

                if (!chain.Build(root))
                {
                    errors = SslPolicyErrors.RemoteCertificateChainErrors;
                    goto sslErrorVerify;
                }

                var subject   = root.Subject;
                var subjectCn = cnRegex.Match(subject).Groups[1].Value;

                if (String.IsNullOrWhiteSpace(subjectCn) || !Utility.MatchHostnameToPattern(task.CurrentRequest.Url.Host, subjectCn))
                {
                    errors = SslPolicyErrors.RemoteCertificateNameMismatch;
                    goto sslErrorVerify;
                }

sslErrorVerify:
                var hostname = task.CurrentRequest.Url.Host;
                bool result = ServicePointManager.ServerCertificateValidationCallback(hostname, root, chain, errors);

                if (result)
                {
                    completionHandler(
                        NSUrlSessionAuthChallengeDisposition.UseCredential,
                        NSUrlCredential.FromTrust(challenge.ProtectionSpace.ServerSecTrust));
                }
                else
                {
                    completionHandler(NSUrlSessionAuthChallengeDisposition.CancelAuthenticationChallenge, null);
                }
                return;

doDefault:
                completionHandler(NSUrlSessionAuthChallengeDisposition.PerformDefaultHandling, challenge.ProposedCredential);
                return;
            }
        void LookupCert()
        {
            var rec = new SecRecord(SecKind.Certificate) {
                Label = labelText
            };

            SecStatusCode rc;
            var rec2 = SecKeyChain.QueryAsRecord(rec, out rc);
            if (rc == SecStatusCode.Success) {
                Console.WriteLine (rec2.Label);
                Console.WriteLine (rec2.ValueData);

                SecCertificate cert = new SecCertificate (rec2.ValueData);

            } else {
                Console.WriteLine (rc);
            }
        }
            public override void DidReceiveChallenge(NSUrlSession session, NSUrlSessionTask task, NSUrlAuthenticationChallenge challenge, Action<NSUrlSessionAuthChallengeDisposition, NSUrlCredential> completionHandler)
            {
               

                if (challenge.ProtectionSpace.AuthenticationMethod == NSUrlProtectionSpace.AuthenticationMethodNTLM) {
                    NetworkCredential credentialsToUse;

                    if (This.Credentials != null) {
                        if (This.Credentials is NetworkCredential) {
                            credentialsToUse = (NetworkCredential)This.Credentials;
                        } else {
                            var uri = this.getResponseForTask(task).Request.RequestUri;
                            credentialsToUse = This.Credentials.GetCredential(uri, "NTLM");
                        }
                        var credential = new NSUrlCredential(credentialsToUse.UserName, credentialsToUse.Password, NSUrlCredentialPersistence.ForSession);
                        completionHandler(NSUrlSessionAuthChallengeDisposition.UseCredential, credential);
                    }
                    return;
                }

                if (challenge.ProtectionSpace.AuthenticationMethod == NSUrlProtectionSpace.AuthenticationMethodClientCertificate)
                {
                    Console.WriteLine("Client Cert!");

                    var password = "******";
                    var options = NSDictionary.FromObjectAndKey(NSObject.FromObject(password), SecImportExport.Passphrase);

                    var path = Path.Combine(NSBundle.MainBundle.BundlePath, "Content", "client.p12");
                    var certData = File.ReadAllBytes(path);

                    NSDictionary[] importResult;

                    X509Certificate cert = new X509Certificate(certData, password);

                    SecStatusCode statusCode = SecImportExport.ImportPkcs12(certData, options, out importResult);
                    var identityHandle = importResult[0][SecImportExport.Identity];
                    var identity = new SecIdentity(identityHandle.Handle);
                    var certificate = new SecCertificate(cert.GetRawCertData());

                    SecCertificate[] certificates = { certificate };
                    NSUrlCredential credential = NSUrlCredential.FromIdentityCertificatesPersistance(identity, certificates, NSUrlCredentialPersistence.ForSession);
                    completionHandler(NSUrlSessionAuthChallengeDisposition.UseCredential, credential);

                    return;
                }

                if (!This.customSSLVerification) {
                    goto doDefault;
                }

                if (challenge.ProtectionSpace.AuthenticationMethod != "NSURLAuthenticationMethodServerTrust") {
                    goto doDefault;
                }

                if (ServicePointManager.ServerCertificateValidationCallback == null) {
                    goto doDefault;
                }

                // Convert Mono Certificates to .NET certificates and build cert 
                // chain from root certificate
                var serverCertChain = challenge.ProtectionSpace.ServerSecTrust;
                var chain = new X509Chain();
                X509Certificate2 root = null;
                var errors = SslPolicyErrors.None;

                if (serverCertChain == null || serverCertChain.Count == 0) { 
                    errors = SslPolicyErrors.RemoteCertificateNotAvailable;
                    goto sslErrorVerify;
                }

                if (serverCertChain.Count == 1) {
                    errors = SslPolicyErrors.RemoteCertificateChainErrors;
                    goto sslErrorVerify;
                }

                var netCerts = Enumerable.Range(0, serverCertChain.Count)
                    .Select(x => serverCertChain[x].ToX509Certificate2())
                    .ToArray();

                for (int i = 1; i < netCerts.Length; i++) {
                    chain.ChainPolicy.ExtraStore.Add(netCerts[i]);
                }

                root = netCerts[0];

                chain.ChainPolicy.RevocationFlag = X509RevocationFlag.EntireChain;
                chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
                chain.ChainPolicy.UrlRetrievalTimeout = new TimeSpan(0, 1, 0);
                chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority;

                if (!chain.Build(root)) {
                    errors = SslPolicyErrors.RemoteCertificateChainErrors;
                    goto sslErrorVerify;
                }

                var subject = root.Subject;
                var subjectCn = cnRegex.Match(subject).Groups[1].Value;

                if (String.IsNullOrWhiteSpace(subjectCn) || !Utility.MatchHostnameToPattern(task.CurrentRequest.Url.Host, subjectCn)) {
                    errors = SslPolicyErrors.RemoteCertificateNameMismatch;
                    goto sslErrorVerify;
                }

            sslErrorVerify:
                var hostname = task.CurrentRequest.Url.Host;
                bool result = ServicePointManager.ServerCertificateValidationCallback(hostname, root, chain, errors);
                if (result) {
                    completionHandler(
                        NSUrlSessionAuthChallengeDisposition.UseCredential,
                        NSUrlCredential.FromTrust(challenge.ProtectionSpace.ServerSecTrust));
                } else {
                    completionHandler(NSUrlSessionAuthChallengeDisposition.CancelAuthenticationChallenge, null);
                }
                return;

            doDefault:
                completionHandler(NSUrlSessionAuthChallengeDisposition.PerformDefaultHandling, challenge.ProposedCredential);
                return;
            }