I'm currently developing a custom scanner in go for OpenVAS. Problem is that the handshake with my custom server fails.
I traced the problem down to error -73
: GNUTLS_E_ASN1_TAG_ERROR
from gnutls_handshake
, but I can't find any resources on that problem. I read something about the certificates being incorrect then but I can't do anything other than regenerating the OpenVAS certificates. The tls functionality in the go server just uses a simple ListenAndServeTLS
and gets the server cert and key.
edit: So this is the relevant network part on the custom scanner:
var (
port = ":1234"
cert = "/usr/local/var/lib/openvas/CA/servercert.pem"
ca = "/usr/local/var/lib/openvas/CA/cacert.pem"
key = "/usr/local/var/lib/openvas/private/CA/serverkey.pem"
)
func start_server() {
ca_file, err := ioutil.ReadFile(ca)
if err != nil {
panic(err)
}
blocks, _ := pem.Decode( ca_file )
ca, err := x509.ParseCertificate(blocks.Bytes)
if err != nil {
panic(err)
}
priv_file, _ := ioutil.ReadFile(key)
blocks2, _ := pem.Decode( priv_file )
priv, err := x509.ParsePKCS1PrivateKey(blocks2.Bytes)
if err != nil {
panic(err)
}
pool := x509.NewCertPool()
pool.AddCert(ca)
cert := tls.Certificate{
Certificate: [][]byte{ca_file},
PrivateKey: priv,
}
config := tls.Config{
ClientAuth: tls.RequireAndVerifyClientCert,
Certificates: []tls.Certificate{cert},
ClientCAs: pool,
}
config.Rand = rand.Reader
service := "0.0.0.0" + port
listener, err := tls.Listen("tcp", service, &config)
if err != nil {
log.Fatalf("server: listen: %s", err)
}
log.Print("server: listening")
for {
conn, err := listener.Accept()
if err != nil {
log.Printf("server: accept: %s", err)
break
}
defer conn.Close()
log.Printf("server: accepted from %s", conn.RemoteAddr())
go handle(conn)
}
}
func handle(conn net.Conn) {
str := "Hello"
defer conn.Close()
buf := make([]byte, 512)
for {
log.Print("server: conn: waiting")
conn.Write( ([]byte)(str) )
n, err := conn.Read(buf)
if err != nil {
if err != nil {
fmt.Println (err)
}
break
}
tlscon, ok := conn.(*tls.Conn)
if ok {
state := tlscon.ConnectionState()
sub := state.PeerCertificates[0].Subject
log.Println(sub)
}
log.Printf("server: conn: echo %q
", string(buf[:n]))
n, err = conn.Write(buf[:n])
n, err = conn.Write(buf[:n])
log.Printf("server: conn: wrote %d bytes", n)
if err != nil {
log.Printf("server: write: %s", err)
break
}
}
log.Println("server: conn: closed")
}
func main() {
start_server()
}
It's taken from an example but it didn't work properly at first ( there was no decode before parsecertificates). Maybe the certificate is mal-formatted now because of that? Before adding the two decodes I had a similar error about the asn1 tags not matching. So also an asn1 error. I thought of generating my own certificate but I don't know if this will not break OpenVAS for the other scanners. I had the same results when just using listenandservetls from go. The error is definitely produced in gnutls_handshake. It's frustrating that I only get an error code from that.