spacemonkeygo / openssl

OpenSSL bindings for Go
http://godoc.org/github.com/spacemonkeygo/openssl
Apache License 2.0
473 stars 236 forks source link

panic in connection write #147

Closed ghost closed 2 years ago

ghost commented 2 years ago

Hello. I got small ssl server on python for test this bug:

#!/usr/bin/python3

import socket
import ssl
import hashlib

def md5(obj):
    m = hashlib.md5()
    m.update(obj)
    return m.hexdigest()

listen_addr = '127.0.0.1'
listen_port = 2099
server_cert = 'server.pem'
server_key = 'key.pem'

context = ssl.SSLContext(ssl.PROTOCOL_TLS)#Tried PROTOCOL_SSLv23 too
context.verify_mode = ssl.CERT_NONE
context.load_cert_chain(certfile=server_cert, keyfile=server_key)

bindsocket = socket.socket()
bindsocket.bind((listen_addr, listen_port))
bindsocket.listen(5)

while True:
    print("Waiting for client")
    newsocket, fromaddr = bindsocket.accept()
    print("Client connected: {}:{}".format(fromaddr[0], fromaddr[1]))
    conn = context.wrap_socket(newsocket, server_side=True)
    print("SSL established. Peer: {}".format(conn.getpeercert()))
    buf = b''  # Buffer to hold received client data
    try:
        while True:
            data = conn.recv(4096)
            if data:
                # Client sent us data. Append to buffer
                buf += data
            else:
                # No more data from client. Show buffer and close connection.
                print("Received:", buf)
                print("MD5:", md5(buf))
                break
    finally:
        print("Closing connection")
        conn.shutdown(socket.SHUT_RDWR)
        conn.close()

Using next code for write some bytes in ssl connection:

package main

import (
    "fmt"
    "github.com/spacemonkeygo/openssl"
)

func main() {
    host := "127.0.0.1"
    port := "2099"

    ctx, _ := openssl.NewCtx()
    ctx.SetVerifyMode(openssl.VerifyNone)
       // conn, _ := openssl.Dial("tcp", host+ ":" + port, ctx, openssl.InsecureSkipHostVerification) - and try this too
    conn, _ := openssl.Dial("tcp", host+ ":" + port, ctx, 0)
    defer conn.Close()

    conn.Write([]byte {0xbe, 0xef, 0xbe, 0xef})

    reply := make([]byte, 4)
    conn.Read(reply)
    fmt.Printf("Response bytes: %q\n", reply)
}

And it got panic:

panic: runtime error: invalid memory address or nil pointer dereference
        panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x34 pc=0x61485e]

goroutine 1 [running]:
github.com/spacemonkeygo/openssl.(*Conn).Close(0x0, 0x0, 0x0)
        /home/anton/go/src/github.com/spacemonkeygo/openssl/conn.go:428 +0x3e
panic(0x6594e0, 0x814740)
        /usr/local/go/src/runtime/panic.go:969 +0x1b9
github.com/spacemonkeygo/openssl.(*Conn).write(0x0, 0xc0000b0400, 0x4, 0x4, 0x0, 0x0)
        /home/anton/go/src/github.com/spacemonkeygo/openssl/conn.go:485 +0x63
github.com/spacemonkeygo/openssl.(*Conn).Write(0x0, 0xc0000b0400, 0x4, 0x4, 0xc0001085a0, 0x0, 0x0)
        /home/anton/go/src/github.com/spacemonkeygo/openssl/conn.go:509 +0xb2
main.main()
        /home/anton/go/src/prj/test1.go:17 +0x15c
exit status 2

If i try go tls library, all good:


import (
    "crypto/tls"
)

func main() {
    host := "127.0.0.1"
    port := "2099"

    config := &tls.Config{InsecureSkipVerify: true}
    conn, err := tls.Dial("tcp", host+ ":" + port, config)
    if err != nil {
        println(err.Error())
    }
    defer conn.Close()

    conn.Write([]byte {0xbe, 0xef, 0xbe, 0xef})

    reply := make([]byte, 4)
    conn.Read(reply)
}

I do something wrong all it is bug?

zeebo commented 2 years ago

The panic is because conn is nil. Check your errors that are being ignored.

ghost commented 2 years ago

Sorry, reason was been in connection err. Tnx.