internal static extern int SslRead(libssl.SafeSslHandle ssl, byte[] buf, int num);
public SslException(string inputMessage, libssl.SslErrorCode error) : this(inputMessage, (int)error) { }
internal static unsafe extern int SslWrite(libssl.SafeSslHandle ssl, byte* buf, int num);
private static void SetSslCertificate(libssl.SafeSslContextHandle contextPtr, SafeX509Handle certPtr, SafeEvpPKeyHandle keyPtr) { Debug.Assert(certPtr != null && !certPtr.IsInvalid, "certPtr != null && !certPtr.IsInvalid"); Debug.Assert(keyPtr != null && !keyPtr.IsInvalid, "keyPtr != null && !keyPtr.IsInvalid"); int retVal = libssl.SSL_CTX_use_certificate(contextPtr, certPtr); if (1 != retVal) { throw CreateSslException(SR.net_ssl_use_cert_failed); } retVal = libssl.SSL_CTX_use_PrivateKey(contextPtr, keyPtr); if (1 != retVal) { throw CreateSslException(SR.net_ssl_use_private_key_failed); } //check private key retVal = libssl.SSL_CTX_check_private_key(contextPtr); if (1 != retVal) { throw CreateSslException(SR.net_ssl_check_private_key_failed); } }
private static SslException CreateSslException(string message, libssl.SslErrorCode error) { string msg = SR.Format(message, error); switch (error) { case libssl.SslErrorCode.SSL_ERROR_SYSCALL: return CreateSslException(msg); case libssl.SslErrorCode.SSL_ERROR_SSL: Exception innerEx = Interop.Crypto.CreateOpenSslCryptographicException(); return new SslException(innerEx.Message, innerEx); default: return new SslException(msg, 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 = Ssl.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; }
private static void UpdateCAListFromRootStore(libssl.SafeSslContextHandle context) { using (SafeX509NameStackHandle nameStack = Crypto.NewX509NameStack()) { //maintaining the HashSet of Certificate's issuer name to keep track of duplicates HashSet<string> issuerNameHashSet = new HashSet<string>(); //Enumerate Certificates from LocalMachine and CurrentUser root store AddX509Names(nameStack, StoreLocation.LocalMachine, issuerNameHashSet); AddX509Names(nameStack, StoreLocation.CurrentUser, issuerNameHashSet); libssl.SSL_CTX_set_client_CA_list(context, nameStack); // The handle ownership has been transferred into the CTX. nameStack.SetHandleAsInvalid(); } }
internal static int Encrypt(SafeSslHandle context, byte[] buffer, int offset, int count, out libssl.SslErrorCode errorCode) { Debug.Assert(buffer != null); Debug.Assert(offset >= 0); Debug.Assert(count >= 0); Debug.Assert(buffer.Length >= offset + count); errorCode = libssl.SslErrorCode.SSL_ERROR_NONE; int retVal; unsafe { fixed (byte* fixedBuffer = buffer) { retVal = Ssl.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(buffer.Length >= capacityNeeded, "Input buffer of size " + buffer.Length + " bytes is insufficient since encryption needs " + capacityNeeded + " bytes."); retVal = BioRead(context.OutputBio, buffer, capacityNeeded); } return retVal; }
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(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 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; }
internal static int Encrypt(IntPtr handlePtr, IntPtr buffer, int offset, int count, int bufferCapacity, out libssl.SslErrorCode errorCode) { errorCode = libssl.SslErrorCode.SSL_ERROR_NONE; SslContext context = Marshal.PtrToStructure<SslContext>(handlePtr); var retVal = libssl.SSL_write(context.sslPtr, new IntPtr(buffer.ToInt64() + offset), count); if (retVal != count) { errorCode = GetSslError(context.sslPtr, 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.writeBioPtr); if (capacityNeeded > bufferCapacity) { throw CreateSslException("OpenSsl::Encrypt capacity needed is more than buffer capacity. capacityNeeded = " + capacityNeeded + "," + "bufferCapacity = " + bufferCapacity); } retVal = BioRead(context.writeBioPtr, buffer, capacityNeeded); if (retVal < 0) { throw CreateSslException("OpenSsl::Encrypt failed"); } } return retVal; }