示例#1
0
 public void SetCertificate(SecIdentity identify, IEnumerable <SecCertificate> certificates)
 {
     using (var array = Bundle(identify, certificates)) {
         var result = SSLSetCertificate(Handle, array.Handle);
         CheckStatusAndThrow(result);
     }
 }
示例#2
0
 public void Identity()
 {
     using (SecIdentity id = GetIdentity()) {
         Assert.NotNull(id.PrivateKey, "PrivateKey");
         Assert.NotNull(id.Certificate, "Certificate");
     }
 }
示例#3
0
        public override void StartHandshake()
        {
            Debug("StartHandshake: {0}", IsServer);

            if (Interlocked.CompareExchange(ref handshakeStarted, 1, 1) != 0)
            {
                throw new InvalidOperationException();
            }

            InitializeConnection();

            SetSessionOption(SslSessionOption.BreakOnCertRequested, true);
            SetSessionOption(SslSessionOption.BreakOnClientAuth, true);
            SetSessionOption(SslSessionOption.BreakOnServerAuth, true);

            if (IsServer)
            {
                SecCertificate[] intermediateCerts;
                serverIdentity = MobileCertificateHelper.GetIdentity(LocalServerCertificate, out intermediateCerts);
                if (serverIdentity == null)
                {
                    throw new SSA.AuthenticationException("Unable to get server certificate from keychain.");
                }

                SetCertificate(serverIdentity, intermediateCerts);
                for (int i = 0; i < intermediateCerts.Length; i++)
                {
                    intermediateCerts [i].Dispose();
                }
            }
        }
示例#4
0
        /// <summary>
        /// Import the specified certificate and its associated private key.
        /// </summary>
        /// <param name="certificate">The certificate and key, in PKCS12 format.</param>
        /// <param name="passphrase">The passphrase that protects the private key.</param>
        public void Import(byte[] certificate, string passphrase)
        {
            NSDictionary opt;

            if (string.IsNullOrEmpty(passphrase))
            {
                opt = new NSDictionary();
            }
            else
            {
                opt = NSDictionary.FromObjectAndKey(new NSString(passphrase), SecImportExport.Passphrase);
            }

            var status = SecImportExport.ImportPkcs12(certificate, opt, out NSDictionary[] array);

            if (status == SecStatusCode.Success)
            {
                var              identity = new SecIdentity(array[0]["identity"].Handle);
                NSArray          chain    = array[0]["chain"] as NSArray;
                SecCertificate[] certs    = new SecCertificate[chain.Count];
                for (System.nuint i = 0; i < chain.Count; i++)
                {
                    certs[i] = chain.GetItem <SecCertificate>(i);
                }
                Credential = new NSUrlCredential(identity, certs, NSUrlCredentialPersistence.ForSession);
            }
        }
        private void SetClientCertificate(ClientCertificate certificate)
        {
            if (certificate == null)
            {
                return;
            }

            byte[] bytes;

            try
            {
                bytes = Convert.FromBase64String(certificate.RawData);
            }
            catch (Exception ex)
            {
                throw new HttpRequestException(FailureMessages.InvalidRawData, ex);
            }

            var options = NSDictionary.FromObjectsAndKeys(new object[] { certificate.Passphrase }, new object[] { "passphrase" });
            var status  = SecImportExport.ImportPkcs12(bytes, options, out NSDictionary[] items);

            var identityRef = items[0]["identity"];
            var identity    = new SecIdentity(identityRef.Handle);

            SecCertificate[] certs = { identity.Certificate };

            this.UrlCredential = new NSUrlCredential(identity, certs, NSUrlCredentialPersistence.ForSession);
        }
示例#6
0
        public void InstallIntoKeyChain(X509Certificate certificate)
        {
            var    provider = DependencyInjector.Get <ICertificateProvider> ();
            string password;
            var    data = provider.GetRawCertificateData(certificate, out password);

            using (var identity = SecIdentity.Import(data, password)) {
                SecKeyChain.AddIdentity(identity);
            }
        }
示例#7
0
        public override void WillSendRequestForAuthenticationChallenge(NSUrlConnection connection, NSUrlAuthenticationChallenge challenge)
        {
            var identity    = SecIdentity.Import(Certificate);
            var certificate = new SecCertificate(Certificate);

            SecCertificate[] certificates = { certificate };

            var credential = NSUrlCredential.FromIdentityCertificatesPersistance(identity, certificates, NSUrlCredentialPersistence.ForSession);

            challenge.Sender.UseCredential(credential, challenge);
        }
示例#8
0
 public MCSession(MCPeerID myPeerID, SecIdentity identity, MCEncryptionPreference encryptionPreference)
     : base(NSObjectFlag.Empty)
 {
     if (identity == null)
     {
         Handle = Init(myPeerID, null, encryptionPreference);
     }
     else
     {
         using (var a = NSArray.FromNSObjects(identity))
             Handle = Init(myPeerID, a, encryptionPreference);
     }
 }
示例#9
0
        public override bool ProcessHandshake()
        {
            if (handshakeFinished)
            {
                throw new NotSupportedException("Handshake already finished.");
            }

            while (true)
            {
                lastException = null;
                var status = SSLHandshake(Handle);
                Debug("Handshake: {0} - {0:x}", status);

                CheckStatusAndThrow(status, SslStatus.WouldBlock, SslStatus.PeerAuthCompleted, SslStatus.PeerClientCertRequested);

                if (status == SslStatus.PeerAuthCompleted)
                {
                    RequirePeerTrust();
                }
                else if (status == SslStatus.PeerClientCertRequested)
                {
                    RequirePeerTrust();
                    if (remoteCertificate == null)
                    {
                        throw new TlsException(AlertDescription.InternalError, "Cannot request client certificate before receiving one from the server.");
                    }
                    localClientCertificate = SelectClientCertificate(remoteCertificate, null);
                    if (localClientCertificate == null)
                    {
                        continue;
                    }
                    clientIdentity = AppleCertificateHelper.GetIdentity(localClientCertificate);
                    if (clientIdentity == null)
                    {
                        throw new TlsException(AlertDescription.CertificateUnknown);
                    }
                    SetCertificate(clientIdentity, new SecCertificate [0]);
                }
                else if (status == SslStatus.WouldBlock)
                {
                    return(false);
                }
                else if (status == SslStatus.Success)
                {
                    handshakeFinished = true;
                    return(true);
                }
            }
        }
示例#10
0
        public static NSUrlCredential FromIdentityCertificatesPersistance(SecIdentity identity, SecCertificate [] certificates, NSUrlCredentialPersistence persistence)
        {
            if (identity == null)
            {
                throw new ArgumentNullException("identity");
            }

            if (certificates == null)
            {
                throw new ArgumentNullException("certificates");
            }

            using (var certs = NSArray.FromNativeObjects(certificates))
                return(FromIdentityCertificatesPersistanceInternal(identity.Handle, certs.Handle, persistence));
        }
示例#11
0
        NSArray Bundle(SecIdentity identity, IEnumerable <SecCertificate> certificates)
        {
            if (identity == null)
            {
                throw new ArgumentNullException("identity");
            }
            int i    = 0;
            int n    = certificates == null ? 0 : certificates.Count();
            var ptrs = new IntPtr [n + 1];

            ptrs [0] = identity.Handle;
            foreach (var certificate in certificates)
            {
                ptrs [++i] = certificate.Handle;
            }
            return(NSArray.FromIntPtrs(ptrs));
        }
示例#12
0
        public override bool ProcessHandshake()
        {
            SslStatus status;

            do
            {
                lastException = null;
                status        = SSLHandshake(Handle);
                Debug("Handshake: {0} - {0:x}", status);

                CheckStatusAndThrow(status, SslStatus.WouldBlock, SslStatus.PeerAuthCompleted, SslStatus.PeerClientCertRequested);

                if (status == SslStatus.PeerAuthCompleted)
                {
                    RequirePeerTrust();
                }
                else if (status == SslStatus.PeerClientCertRequested)
                {
                    RequirePeerTrust();
                    if (remoteCertificate == null)
                    {
                        throw new TlsException(AlertDescription.InternalError, "Cannot request client certificate before receiving one from the server.");
                    }
                    localClientCertificate = MobileCertificateHelper.SelectClientCertificate(TargetHost, certificateValidator, ClientCertificates, remoteCertificate);
                    if (localClientCertificate == null)
                    {
                        continue;
                    }
                    clientIdentity = MobileCertificateHelper.GetIdentity(localClientCertificate);
                    if (clientIdentity == null)
                    {
                        throw new TlsException(AlertDescription.CertificateUnknown);
                    }
                    SetCertificate(clientIdentity, new SecCertificate [0]);
                }
                else if (status == SslStatus.WouldBlock)
                {
                    return(false);
                }
            } while (status != SslStatus.Success);

            return(true);
        }
        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));
            }
        }
示例#14
0
 public MCSession(MCPeerID myPeerID, SecIdentity identity, SecCertificate[] certificates, MCEncryptionPreference encryptionPreference)
     : base(NSObjectFlag.Empty)
 {
     if (identity == null)
     {
         if (certificates == null)
         {
             Handle = Init(myPeerID, null, encryptionPreference);
         }
         else
         {
             throw new ArgumentNullException("identity");
         }
     }
     else
     {
         using (var certs = NSArray.FromNativeObjects(certificates))
             Handle = Init(myPeerID, certs, encryptionPreference);
     }
 }
示例#15
0
        /// <summary>
        /// Import the specified certificate and its associated private key.
        /// </summary>
        /// <param name="certificate">The certificate and key, in PKCS12 format.</param>
        /// <param name="passphrase">The passphrase that protects the private key.</param>
        public void Import(byte[] certificate, string passphrase)
        {
            NSDictionary opt;

            if (string.IsNullOrEmpty(passphrase))
            {
                opt = new NSDictionary();
            }
            else
            {
                opt = NSDictionary.FromObjectAndKey(new NSString(passphrase), SecImportExport.Passphrase);
            }

            var status = SecImportExport.ImportPkcs12(certificate, opt, out NSDictionary[] array);

            if (status == SecStatusCode.Success)
            {
                var identity           = new SecIdentity(array[0]["identity"].Handle);
                SecCertificate[] certs = { identity.Certificate };
                Credential = new NSUrlCredential(identity, certs, NSUrlCredentialPersistence.ForSession);
            }
        }
示例#16
0
 protected override void Dispose(bool disposing)
 {
     try {
         if (disposed)
         {
             return;
         }
         if (disposing)
         {
             disposed = true;
             if (serverIdentity != null)
             {
                 serverIdentity.Dispose();
                 serverIdentity = null;
             }
             if (clientIdentity != null)
             {
                 clientIdentity.Dispose();
                 clientIdentity = null;
             }
             if (remoteCertificate != null)
             {
                 remoteCertificate.Dispose();
                 remoteCertificate = null;
             }
         }
     } finally {
         disposed = true;
         if (context != IntPtr.Zero)
         {
             CFObject.CFRelease(context);
             context = IntPtr.Zero;
         }
         base.Dispose(disposing);
     }
 }
示例#17
0
 public NSURLCredential(SecIdentity identity, AnyObject[] certificates, NSURLCredentialPersistence persistence)
 {
 }
示例#18
0
 public NSUrlCredential(SecIdentity identity, SecCertificate [] certificates, NSUrlCredentialPersistence persistence)
     : this(identity.Handle, NSArray.FromNativeObjects(certificates).Handle, persistence)
 {
 }
            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;
            }
示例#20
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;
            }
示例#21
0
 public NSURLCredential([Unwrapped] SecIdentity identity, AnyObject[] certificates, NSURLCredentialPersistence persistence, bool NAME_YOUR_PARAMS = false)
 {
 }