Example #1
0
 private static libssl.SslErrorCode GetSslError(IntPtr sslPtr, int result)
 {
     libssl.SslErrorCode retVal = libssl.SSL_get_error(sslPtr, result);
     if (retVal == libssl.SslErrorCode.SSL_ERROR_SYSCALL)
     {
         retVal = (libssl.SslErrorCode)libssl.ERR_get_error();
     }
     return(retVal);
 }
Example #2
0
 private static libssl.SslErrorCode GetSslError(SafeSslHandle context, int result)
 {
     libssl.SslErrorCode retVal = libssl.SSL_get_error(context, result);
     if (retVal == libssl.SslErrorCode.SSL_ERROR_SYSCALL)
     {
         retVal = (libssl.SslErrorCode)libssl.ERR_get_error();
     }
     return(retVal);
 }
Example #3
0
        private static SslException CreateSslException(string message, libssl.SslErrorCode error)
        {
            switch (error)
            {
            case libssl.SslErrorCode.SSL_ERROR_SYSCALL:
                return(new SslException(message, error));

            case libssl.SslErrorCode.SSL_ERROR_SSL:
                Exception innerEx = Interop.libcrypto.CreateOpenSslCryptographicException();
                return(new SslException(innerEx.Message, innerEx));

            default:
                return(new SslException(message + ": " + error, error));
            }
        }
Example #4
0
        internal static bool DoSslHandshake(IntPtr sslContextPtr, IntPtr recvPtr, int recvCount, out IntPtr sendPtr, out int sendCount)
        {
            sendPtr   = IntPtr.Zero;
            sendCount = 0;
            SslContext context  = Marshal.PtrToStructure <SslContext>(sslContextPtr);
            bool       isServer = context.isServer;

            if ((IntPtr.Zero != recvPtr) && (recvCount > 0))
            {
                BioWrite(context.readBioPtr, recvPtr, recvCount);
            }

            int retVal = libssl.SSL_do_handshake(context.sslPtr);

            if (retVal != 1)
            {
                libssl.SslErrorCode error = GetSslError(context.sslPtr, retVal);

                if ((retVal != -1) || (error != libssl.SslErrorCode.SSL_ERROR_WANT_READ))
                {
                    throw CreateSslException(context.sslPtr, "SSL Handshake failed: ", retVal);
                }
            }

            sendCount = libssl.BIO_ctrl_pending(context.writeBioPtr);

            if (sendCount > 0)
            {
                sendPtr   = Marshal.AllocHGlobal(sendCount);
                sendCount = BioRead(context.writeBioPtr, sendPtr, sendCount);
                if (sendCount <= 0)
                {
                    int errorCode = sendCount;
                    Marshal.FreeHGlobal(sendPtr);
                    sendPtr   = IntPtr.Zero;
                    sendCount = 0;
                    throw CreateSslException(context.sslPtr, "Read Bio failed: ", errorCode);
                }
            }

            return((libssl.SSL_state(context.sslPtr) == (int)libssl.SslState.SSL_ST_OK));
        }
Example #5
0
 public SslException(string inputMessage, libssl.SslErrorCode error)
     : this(inputMessage, (int)error)
 {
 }
Example #6
0
        internal static int Decrypt(SafeSslHandle context, byte[] outBuffer, int count, out libssl.SslErrorCode errorCode)
        {
            errorCode = libssl.SslErrorCode.SSL_ERROR_NONE;

            int retVal = BioWrite(context.InputBio, outBuffer, 0, count);

            if (retVal == count)
            {
                retVal = Crypto.SslRead(context, outBuffer, retVal);

                if (retVal > 0)
                {
                    count = retVal;
                }
            }

            if (retVal != count)
            {
                errorCode = GetSslError(context, retVal);
                retVal    = 0;

                switch (errorCode)
                {
                // indicate end-of-file
                case libssl.SslErrorCode.SSL_ERROR_ZERO_RETURN:
                    break;

                case libssl.SslErrorCode.SSL_ERROR_WANT_READ:
                    // update error code to renegotiate if renegotiate is pending, otherwise make it SSL_ERROR_WANT_READ
                    errorCode = libssl.SSL_renegotiate_pending(context) == 1 ?
                                libssl.SslErrorCode.SSL_ERROR_RENEGOTIATE :
                                libssl.SslErrorCode.SSL_ERROR_WANT_READ;
                    break;

                default:
                    throw CreateSslException(SR.net_ssl_decrypt_failed, errorCode);
                }
            }

            return(retVal);
        }
Example #7
0
        internal static int Encrypt(SafeSslHandle context, byte[] buffer, int offset, int count, int bufferCapacity, out libssl.SslErrorCode errorCode)
        {
            errorCode = libssl.SslErrorCode.SSL_ERROR_NONE;

            int retVal;

            unsafe
            {
                fixed(byte *fixedBuffer = buffer)
                {
                    retVal = Crypto.SslWrite(context, fixedBuffer + offset, count);
                }
            }

            if (retVal != count)
            {
                errorCode = GetSslError(context, retVal);
                retVal    = 0;

                switch (errorCode)
                {
                // indicate end-of-file
                case libssl.SslErrorCode.SSL_ERROR_ZERO_RETURN:
                case libssl.SslErrorCode.SSL_ERROR_WANT_READ:
                    break;

                default:
                    throw CreateSslException(SR.net_ssl_encrypt_failed, errorCode);
                }
            }
            else
            {
                int capacityNeeded = libssl.BIO_ctrl_pending(context.OutputBio);

                Debug.Assert(bufferCapacity >= capacityNeeded, "Input buffer of size " + bufferCapacity +
                             " bytes is insufficient since encryption needs " + capacityNeeded + " bytes.");

                retVal = BioRead(context.OutputBio, buffer, capacityNeeded);
            }

            return(retVal);
        }
Example #8
0
 public SslException(string inputMessage, libssl.SslErrorCode error) : base(inputMessage)
 {
     HResult = (int)error;
 }
Example #9
0
        internal static int Encrypt(SafeSslHandle context, IntPtr buffer, int offset, int count, int bufferCapacity, out libssl.SslErrorCode errorCode)
        {
            errorCode = libssl.SslErrorCode.SSL_ERROR_NONE;

            int retVal = libssl.SSL_write(context, new IntPtr(buffer.ToInt64() + offset), count);

            if (retVal != count)
            {
                errorCode = GetSslError(context, retVal);
                retVal    = 0;

                switch (errorCode)
                {
                // indicate end-of-file
                case libssl.SslErrorCode.SSL_ERROR_ZERO_RETURN:
                case libssl.SslErrorCode.SSL_ERROR_WANT_READ:
                    break;

                default:
                    throw CreateSslException("OpenSsl::Encrypt failed");
                }
            }
            else
            {
                int capacityNeeded = libssl.BIO_ctrl_pending(context.OutputBio);

                if (capacityNeeded > bufferCapacity)
                {
                    throw CreateSslException("OpenSsl::Encrypt capacity needed is more than buffer capacity. capacityNeeded = " + capacityNeeded + "," + "bufferCapacity = " + bufferCapacity);
                }

                retVal = BioRead(context.OutputBio, buffer, capacityNeeded);

                if (retVal < 0)
                {
                    throw CreateSslException("OpenSsl::Encrypt failed");
                }
            }

            return(retVal);
        }
Example #10
0
        internal static int Decrypt(IntPtr sslContextPtr, IntPtr outBufferPtr, int count, out libssl.SslErrorCode errorCode)
        {
            errorCode = libssl.SslErrorCode.SSL_ERROR_NONE;

            SslContext context = Marshal.PtrToStructure <SslContext>(sslContextPtr);

            int retVal = BioWrite(context.readBioPtr, outBufferPtr, count);

            if (retVal == count)
            {
                retVal = libssl.SSL_read(context.sslPtr, outBufferPtr, retVal);

                if (retVal > 0)
                {
                    count = retVal;
                }
            }

            if (retVal != count)
            {
                errorCode = GetSslError(context.sslPtr, retVal);
                retVal    = 0;

                switch (errorCode)
                {
                // indicate end-of-file
                case libssl.SslErrorCode.SSL_ERROR_ZERO_RETURN:
                    break;

                case libssl.SslErrorCode.SSL_ERROR_WANT_READ:
                    // update error code to renegotiate if renegotiate is pending, otherwise make it SSL_ERROR_WANT_READ
                    errorCode = libssl.SSL_renegotiate_pending(context.sslPtr) == 1 ?
                                libssl.SslErrorCode.SSL_ERROR_RENEGOTIATE :
                                libssl.SslErrorCode.SSL_ERROR_WANT_READ;
                    break;

                default:
                    throw CreateSslException("OpenSsl::Decrypt failed");
                }
            }

            return(retVal);
        }