コード例 #1
0
ファイル: SslHelper.cs プロジェクト: dotcomboom/EbIRC
        private int ValidateCert(uint dwType, IntPtr pvArg, uint dwChainLen, IntPtr pCertChain, uint dwFlags)
        {
            //According to http://msdn.microsoft.com/en-us/library/ms940451.aspx:
            //
            //- dwChainLen is always 1
            //- Windows CE performs the cert chain validation
            //- pvArg is the context data we passed into the SO_SSL_SET_VALIDATE_CERT_HOOK call so in our
            //- case is the host name
            //
            //So here we are responsible for validating the dates on the certificate and the CN

            if (!m_validateCertEnabled)
            {
                m_lastValidateCertError = SslValidateErrors.NotValidate;
                return(SSL_ERR_OKAY);
            }

            if (dwType != SSL_CERT_X59)
            {
                m_lastValidateCertError = SslValidateErrors.BadData;
                return(SSL_ERR_BAD_TYPE);
            }

            //When in debug mode let self-signed certificates through ...
#if !DEBUG
            if ((dwFlags & SSL_CERT_FLAG_ISSUER_UNKNOWN) != 0)
            {
                m_lastValidateCertError = SslValidateErrors.InvalidIssuer;
                return(SSL_ERR_CERT_UNKNOWN);
            }
#endif

            Debug.Assert(dwChainLen == 1);

            //Note about the note: an unmanaged long is 32 bits, unlike a managed long which is 64. I was missing
            //this fact when I wrote the comment. So the docs are accurate.
            //NOTE: The documentation says pCertChain is a pointer to a LPBLOB struct:
            //
            // {ulong size, byte* data}
            //
            //in reality the size is a 32 bit integer (not 64).
            int    certSize = Marshal.ReadInt32(pCertChain);
            IntPtr pData    = Marshal.ReadIntPtr(new IntPtr(pCertChain.ToInt32() + sizeof(int)));

            byte[] certData = new byte[certSize];

            for (int i = 0; i < certSize; i++)
            {
                certData[i] = Marshal.ReadByte(pData, (int)i);
            }

            X509Certificate2 cert;
            try
            {
                cert = new X509Certificate2(certData);
            }
            catch (ArgumentException) {
                m_lastValidateCertError = SslValidateErrors.BadData;
                return(SSL_ERR_BAD_DATA);
            }
            catch (CryptographicException)
            {
                m_lastValidateCertError = SslValidateErrors.BadData;
                return(SSL_ERR_BAD_DATA);
            }

            //Validate the expiration date
            if (DateTime.Now > DateTime.Parse(cert.GetExpirationDateString(), CultureInfo.CurrentCulture))
            {
                m_lastValidateCertError = SslValidateErrors.Expired;
                return(SSL_ERR_CERT_EXPIRED);
            }

            //Validate the effective date
            if (DateTime.Now < DateTime.Parse(cert.GetEffectiveDateString(), CultureInfo.CurrentCulture))
            {
                m_lastValidateCertError = SslValidateErrors.NotEffectDate;
                return(SSL_ERR_FAILED);
            }

            string certName = cert.GetName();
            Debug.WriteLine(certName);

            //Validate the CN
            string host = ReadAnsiString(pvArg);
            if (!certName.Contains("CN=" + host))
            {
                m_lastValidateCertError = SslValidateErrors.OtherSite;
                return(SSL_ERR_FAILED);
            }

            m_lastValidateCertError = SslValidateErrors.Okay;
            return(SSL_ERR_OKAY);
        }
コード例 #2
0
ファイル: SslHelper.cs プロジェクト: iseebi/EbIRC
        private int ValidateCert(uint dwType, IntPtr pvArg, uint dwChainLen, IntPtr pCertChain, uint dwFlags)
        {
            //According to http://msdn.microsoft.com/en-us/library/ms940451.aspx:
            //
            //- dwChainLen is always 1
            //- Windows CE performs the cert chain validation
            //- pvArg is the context data we passed into the SO_SSL_SET_VALIDATE_CERT_HOOK call so in our
            //- case is the host name
            //
            //So here we are responsible for validating the dates on the certificate and the CN

            if (!m_validateCertEnabled)
            {
                m_lastValidateCertError = SslValidateErrors.NotValidate;
                return SSL_ERR_OKAY;
            }

            if (dwType != SSL_CERT_X59)
            {
                m_lastValidateCertError = SslValidateErrors.BadData;
                return SSL_ERR_BAD_TYPE;
            }

            //When in debug mode let self-signed certificates through ...
            #if !DEBUG
            if ((dwFlags & SSL_CERT_FLAG_ISSUER_UNKNOWN) != 0)
            {
                m_lastValidateCertError = SslValidateErrors.InvalidIssuer;
                return SSL_ERR_CERT_UNKNOWN;
            }
            #endif

            Debug.Assert(dwChainLen == 1);

            //Note about the note: an unmanaged long is 32 bits, unlike a managed long which is 64. I was missing
            //this fact when I wrote the comment. So the docs are accurate.
            //NOTE: The documentation says pCertChain is a pointer to a LPBLOB struct:
            //
            // {ulong size, byte* data}
            //
            //in reality the size is a 32 bit integer (not 64).
            int certSize = Marshal.ReadInt32(pCertChain);
            IntPtr pData = Marshal.ReadIntPtr(new IntPtr(pCertChain.ToInt32() + sizeof(int)));

            byte[] certData = new byte[certSize];

            for (int i = 0; i < certSize; i++)
                certData[i] = Marshal.ReadByte(pData, (int)i);

            X509Certificate2 cert;
            try
            {
                cert = new X509Certificate2(certData);
            }
            catch (ArgumentException) {
                m_lastValidateCertError = SslValidateErrors.BadData;
                return SSL_ERR_BAD_DATA;
            }
            catch (CryptographicException)
            {
                m_lastValidateCertError = SslValidateErrors.BadData;
                return SSL_ERR_BAD_DATA;
            }

            //Validate the expiration date
            if (DateTime.Now > DateTime.Parse(cert.GetExpirationDateString(), CultureInfo.CurrentCulture))
            {
                m_lastValidateCertError = SslValidateErrors.Expired;
                return SSL_ERR_CERT_EXPIRED;
            }

            //Validate the effective date
            if (DateTime.Now < DateTime.Parse(cert.GetEffectiveDateString(), CultureInfo.CurrentCulture))
            {
                m_lastValidateCertError = SslValidateErrors.NotEffectDate;
                return SSL_ERR_FAILED;
            }

            string certName = cert.GetName();
            Debug.WriteLine(certName);

            //Validate the CN
            string host = ReadAnsiString(pvArg);
            if (!certName.Contains("CN=" + host))
            {
                m_lastValidateCertError = SslValidateErrors.OtherSite;
                return SSL_ERR_FAILED;
            }

            m_lastValidateCertError = SslValidateErrors.Okay;
            return SSL_ERR_OKAY;
        }