Exemple #1
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 = AppleCertificateHelper.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();
                }
            }
        }
Exemple #2
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);
                }
            }
        }
        public override void StartHandshake()
        {
            Debug("StartHandshake: {0}", IsServer);

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

            InitializeConnection();

            /*
             * SecureTransport is bugged OS X 10.5.8+ - renegotiation after
             * calling SetCertificate() will not work.
             *
             * We also cannot change options after the handshake has started,
             * so if you want to request a client certificate, it will happen
             * both during the initial handshake and during renegotiation.
             *
             * You may check 'SslStream.IsAuthenticated' (which will be false
             * during the initial handshake) from within your
             * 'LocalCertificateSelectionCallback' and return null to have the
             * callback invoked again during renegotiation.
             *
             * However, the first time your selection callback returns a client
             * certificate, that certificate will be used for the rest of the
             * session.
             */

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

            if (IsServer)
            {
                SafeSecCertificateHandle[] intermediateCerts;
                serverIdentity = AppleCertificateHelper.GetIdentity(LocalServerCertificate, out intermediateCerts);
                if (serverIdentity.IsInvalid)
                {
                    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();
                }
            }
        }
        void SetServerIdentity(X509Certificate certificate)
        {
            using (var serverIdentity = AppleCertificateHelper.GetIdentity(certificate, out var intermediateCerts)) {
                if (serverIdentity.IsInvalid)
                {
                    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();
                }
            }
        }
        void ClientCertificateRequested()
        {
            EvaluateTrust();
            var acceptableIssuers = CopyDistinguishedNames();

            localClientCertificate = SelectClientCertificate(acceptableIssuers);
            if (localClientCertificate == null)
            {
                return;
            }
            clientIdentity = AppleCertificateHelper.GetIdentity(localClientCertificate);
            if (clientIdentity.IsInvalid)
            {
                throw new TlsException(AlertDescription.CertificateUnknown);
            }
            SetCertificate(clientIdentity, new SafeSecCertificateHandle [0]);
        }