From 21b4fa8d2a511b2b7e7215bb18cb3836173fb390 Mon Sep 17 00:00:00 2001 From: jsing <> Date: Fri, 31 Oct 2014 14:10:55 +0000 Subject: Update regress for the libressl to libtls rename. --- src/regress/lib/libtls/Makefile | 8 ++ src/regress/lib/libtls/gotls/Makefile | 15 +++ src/regress/lib/libtls/gotls/tls.go | 165 +++++++++++++++++++++++++++++++ src/regress/lib/libtls/gotls/tls_test.go | 100 +++++++++++++++++++ 4 files changed, 288 insertions(+) create mode 100644 src/regress/lib/libtls/Makefile create mode 100644 src/regress/lib/libtls/gotls/Makefile create mode 100644 src/regress/lib/libtls/gotls/tls.go create mode 100644 src/regress/lib/libtls/gotls/tls_test.go (limited to 'src') diff --git a/src/regress/lib/libtls/Makefile b/src/regress/lib/libtls/Makefile new file mode 100644 index 0000000000..fc1e97a3b5 --- /dev/null +++ b/src/regress/lib/libtls/Makefile @@ -0,0 +1,8 @@ +# $OpenBSD: Makefile,v 1.1 2014/10/31 14:10:55 jsing Exp $ + +SUBDIR= \ + gotls + +install: + +.include diff --git a/src/regress/lib/libtls/gotls/Makefile b/src/regress/lib/libtls/gotls/Makefile new file mode 100644 index 0000000000..56286feec9 --- /dev/null +++ b/src/regress/lib/libtls/gotls/Makefile @@ -0,0 +1,15 @@ +# $OpenBSD: Makefile,v 1.1 2014/10/31 14:10:55 jsing Exp $ + +GO_VERSION != sh -c "(go version) 2>/dev/null || true" + +.if empty(GO_VERSION) +regress: + @echo golang is required for this regress... skipping +.endif + +REGRESS_TARGETS=regress-gotls + +regress-gotls: + cd ${.CURDIR} && go test -test.v . + +.include diff --git a/src/regress/lib/libtls/gotls/tls.go b/src/regress/lib/libtls/gotls/tls.go new file mode 100644 index 0000000000..7f490492bc --- /dev/null +++ b/src/regress/lib/libtls/gotls/tls.go @@ -0,0 +1,165 @@ +// Package tls provides a Go interface to the libtls library. +package tls + +/* +#cgo LDFLAGS: -ltls -lssl -lcrypto + +#include + +#include + +typedef void *tls; +*/ +import "C" + +import ( + "errors" + "fmt" + "unsafe" +) + +// TLSConfig provides configuration options for a TLS context. +type TLSConfig struct { + caFile *C.char + tlsCfg *C.struct_tls_config +} + +// TLS encapsulates the TLS context. +type TLS struct { + cfg *TLSConfig + ctx *C.struct_tls +} + +// Init initialises the TLS library. +func Init() error { + if C.tls_init() != 0 { + return errors.New("initialisation failed") + } + return nil +} + +// NewConfig returns a new TLS configuration. +func NewConfig() (*TLSConfig, error) { + cfg := C.tls_config_new() + if cfg == nil { + return nil, errors.New("failed to allocate config") + } + return &TLSConfig{ + tlsCfg: cfg, + }, nil +} + +// SetCAFile sets the CA file to be used for connections. +func (c *TLSConfig) SetCAFile(filename string) { + if c.caFile != nil { + C.free(unsafe.Pointer(c.caFile)) + } + c.caFile = C.CString(filename) + C.tls_config_set_ca_file(c.tlsCfg, c.caFile) +} + +// InsecureNoVerifyCert disables certificate verification for the connection. +func (c *TLSConfig) InsecureNoVerifyCert() { + C.tls_config_insecure_noverifycert(c.tlsCfg) +} + +// InsecureNoVerifyHost disables hostname verification for the connection. +func (c *TLSConfig) InsecureNoVerifyHost() { + C.tls_config_insecure_noverifyhost(c.tlsCfg) +} + +// SetSecure enables verification for the connection. +func (c *TLSConfig) SetVerify() { + C.tls_config_verify(c.tlsCfg) +} + +// Free frees resources associated with the TLS configuration. +func (c *TLSConfig) Free() { + if c.tlsCfg == nil { + return + } + C.tls_config_free(c.tlsCfg) + c.tlsCfg = nil +} + +// NewClient returns a new TLS client context, using the optional configuration. +// If no configuration is specified the default configuration will be used. +func NewClient(config *TLSConfig) (*TLS, error) { + var sslCfg *C.struct_tls_config + if config != nil { + sslCfg = config.tlsCfg + } + ctx := C.tls_client() + if ctx == nil { + return nil, errors.New("tls client failed") + } + if C.tls_configure(ctx, sslCfg) != 0 { + return nil, errors.New("tls configure failed") + } + return &TLS{ + cfg: config, + ctx: ctx, + }, nil +} + +// Error returns the error message from the TLS context. +func (t *TLS) Error() string { + if msg := C.tls_error(t.ctx); msg != nil { + return C.GoString(msg) + } + return "" +} + +// Connect attempts to establish an TLS connection to the specified host on +// the given port. The host may optionally contain a colon separated port +// value if the port string is specified as an empty string. +func (t *TLS) Connect(host, port string) error { + h := C.CString(host) + var p *C.char + if port != "" { + p = C.CString(port) + } + defer C.free(unsafe.Pointer(h)) + defer C.free(unsafe.Pointer(p)) + if C.tls_connect(t.ctx, h, p) != 0 { + return fmt.Errorf("connect failed: %v", t.Error()) + } + return nil +} + +// Read reads data the TLS connection into the given buffer. +func (t *TLS) Read(buf []byte) (int, error) { + var inlen C.size_t + if C.tls_read(t.ctx, unsafe.Pointer(&buf[0]), C.size_t(len(buf)), (*C.size_t)(unsafe.Pointer(&inlen))) != 0 { + return -1, fmt.Errorf("read failed: %v", t.Error()) + } + return int(inlen), nil +} + +// Write writes the given data to the TLS connection. +func (t *TLS) Write(buf []byte) (int, error) { + var outlen C.size_t + p := C.CString(string(buf)) + defer C.free(unsafe.Pointer(p)) + if C.tls_write(t.ctx, unsafe.Pointer(p), C.size_t(len(buf)), (*C.size_t)(unsafe.Pointer(&outlen))) != 0 { + return -1, fmt.Errorf("write failed: %v", t.Error()) + } + return int(outlen), nil +} + +// Close closes the TLS connection. +func (t *TLS) Close() error { + if C.tls_close(t.ctx) != 0 { + return fmt.Errorf("close failed: %v", t.Error()) + } + return nil +} + +// Free frees resources associated with the TLS context. +func (t *TLS) Free() { + if t.ctx == nil { + return + } + C.tls_free(t.ctx) + t.ctx = nil +} diff --git a/src/regress/lib/libtls/gotls/tls_test.go b/src/regress/lib/libtls/gotls/tls_test.go new file mode 100644 index 0000000000..f709fcb455 --- /dev/null +++ b/src/regress/lib/libtls/gotls/tls_test.go @@ -0,0 +1,100 @@ +package tls + +import ( + "encoding/pem" + "fmt" + "io/ioutil" + "net/http" + "net/http/httptest" + "net/url" + "os" + "strings" + "testing" +) + +// createCAFile writes a PEM encoded version of the certificate out to a +// temporary file, for use by libtls. +func createCAFile(cert []byte) (string, error) { + f, err := ioutil.TempFile("", "tls") + if err != nil { + return "", fmt.Errorf("failed to create file: %v", err) + } + defer f.Close() + block := &pem.Block{ + Type: "CERTIFICATE", + Bytes: cert, + } + if err := pem.Encode(f, block); err != nil { + return "", fmt.Errorf("failed to encode certificate: %v", err) + } + return f.Name(), nil +} + +const httpContent = "Hello, TLS!" + +func TestTLSBasic(t *testing.T) { + ts := httptest.NewTLSServer( + http.HandlerFunc( + func(w http.ResponseWriter, r *http.Request) { + fmt.Fprintln(w, httpContent) + }, + ), + ) + defer ts.Close() + + u, err := url.Parse(ts.URL) + if err != nil { + t.Fatalf("Failed to parse URL %q: %v", ts.URL, err) + } + + caFile, err := createCAFile(ts.TLS.Certificates[0].Certificate[0]) + if err != nil { + t.Fatalf("Failed to create CA file: %v", err) + } + defer os.Remove(caFile) + + if err := Init(); err != nil { + t.Fatal(err) + } + + cfg, err := NewConfig() + if err != nil { + t.Fatal(err) + } + defer cfg.Free() + cfg.SetCAFile(caFile) + + tls, err := NewClient(cfg) + if err != nil { + t.Fatal(err) + } + defer tls.Free() + + t.Logf("Connecting to %s", u.Host) + + if err := tls.Connect(u.Host, ""); err != nil { + t.Fatal(err) + } + defer func() { + if err := tls.Close(); err != nil { + t.Logf("Close failed: %v", err) + } + }() + + n, err := tls.Write([]byte("GET / HTTP/1.0\n\n")) + if err != nil { + t.Fatal(err) + } + t.Logf("Wrote %d bytes...", n) + + buf := make([]byte, 1024) + n, err = tls.Read(buf) + if err != nil { + t.Fatal(err) + } + t.Logf("Read %d bytes...", n) + + if !strings.Contains(string(buf), httpContent) { + t.Errorf("Response does not contain %q", httpContent) + } +} -- cgit v1.2.3-55-g6feb