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); }
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); }
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)); } }
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)); }
public SslException(string inputMessage, libssl.SslErrorCode error) : this(inputMessage, (int)error) { }
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); }
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); }
public SslException(string inputMessage, libssl.SslErrorCode error) : base(inputMessage) { HResult = (int)error; }
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); }
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); }