package main import ( "crypto/tls" "crypto/x509" "fmt" "io" "net/http" "os" ) type SFSConnection struct { tlsConn *tls.Conn writing bool credentials Credentials isAuthed bool } type Credentials struct { user string pass string } func NewSFSConnection(host string, port int) (*SFSConnection, error) { _, err := os.Stat("./public.cer") if err != nil { getPublicKey() } cert, err := os.ReadFile("./public.cer") if err != nil { return nil, fmt.Errorf("error reading cert from ./public.cer: %v", err) } certPool := x509.NewCertPool() if ok := certPool.AppendCertsFromPEM(cert); !ok { return nil, fmt.Errorf("error loading certificate %v into cert pool", cert) } config := &tls.Config{ RootCAs: certPool, CipherSuites: []uint16{ tls.TLS_AES_128_GCM_SHA256, tls.TLS_AES_256_GCM_SHA384, tls.TLS_CHACHA20_POLY1305_SHA256, }, } conn, err := tls.Dial("tcp", fmt.Sprintf("%s:%d", host, port), config) if err != nil { return nil, err } return &SFSConnection{ conn, false, Credentials{"", ""}, true, }, nil } func getPublicKey() { out, err := os.Create("./public.cer") if err != nil { fmt.Printf("Error closing file writer: %v", err) os.Exit(1) } defer out.Close() serverAddr, err := Config.GetKey("General.http-server") if err != nil { fmt.Printf("Error getting key in config: %v", err) os.Exit(1) } resp, err := http.Get(serverAddr.String() + "/public.cer") if err != nil { fmt.Printf("Error fetching public key: %v", err) os.Exit(1) } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { fmt.Printf("Request was unseccessful with code %v", resp.StatusCode) } _, err = io.Copy(out, resp.Body) if err != nil { fmt.Printf("Error writing public key to file: %v", err) os.Exit(1) } }