summaryrefslogtreecommitdiff
path: root/src/regress/lib/libtls/gotls/tls.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/regress/lib/libtls/gotls/tls.go')
-rw-r--r--src/regress/lib/libtls/gotls/tls.go165
1 files changed, 165 insertions, 0 deletions
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 @@
1// Package tls provides a Go interface to the libtls library.
2package tls
3
4/*
5#cgo LDFLAGS: -ltls -lssl -lcrypto
6
7#include <stdlib.h>
8
9#include <tls.h>
10
11typedef void *tls;
12*/
13import "C"
14
15import (
16 "errors"
17 "fmt"
18 "unsafe"
19)
20
21// TLSConfig provides configuration options for a TLS context.
22type TLSConfig struct {
23 caFile *C.char
24 tlsCfg *C.struct_tls_config
25}
26
27// TLS encapsulates the TLS context.
28type TLS struct {
29 cfg *TLSConfig
30 ctx *C.struct_tls
31}
32
33// Init initialises the TLS library.
34func Init() error {
35 if C.tls_init() != 0 {
36 return errors.New("initialisation failed")
37 }
38 return nil
39}
40
41// NewConfig returns a new TLS configuration.
42func NewConfig() (*TLSConfig, error) {
43 cfg := C.tls_config_new()
44 if cfg == nil {
45 return nil, errors.New("failed to allocate config")
46 }
47 return &TLSConfig{
48 tlsCfg: cfg,
49 }, nil
50}
51
52// SetCAFile sets the CA file to be used for connections.
53func (c *TLSConfig) SetCAFile(filename string) {
54 if c.caFile != nil {
55 C.free(unsafe.Pointer(c.caFile))
56 }
57 c.caFile = C.CString(filename)
58 C.tls_config_set_ca_file(c.tlsCfg, c.caFile)
59}
60
61// InsecureNoVerifyCert disables certificate verification for the connection.
62func (c *TLSConfig) InsecureNoVerifyCert() {
63 C.tls_config_insecure_noverifycert(c.tlsCfg)
64}
65
66// InsecureNoVerifyHost disables hostname verification for the connection.
67func (c *TLSConfig) InsecureNoVerifyHost() {
68 C.tls_config_insecure_noverifyhost(c.tlsCfg)
69}
70
71// SetSecure enables verification for the connection.
72func (c *TLSConfig) SetVerify() {
73 C.tls_config_verify(c.tlsCfg)
74}
75
76// Free frees resources associated with the TLS configuration.
77func (c *TLSConfig) Free() {
78 if c.tlsCfg == nil {
79 return
80 }
81 C.tls_config_free(c.tlsCfg)
82 c.tlsCfg = nil
83}
84
85// NewClient returns a new TLS client context, using the optional configuration.
86// If no configuration is specified the default configuration will be used.
87func NewClient(config *TLSConfig) (*TLS, error) {
88 var sslCfg *C.struct_tls_config
89 if config != nil {
90 sslCfg = config.tlsCfg
91 }
92 ctx := C.tls_client()
93 if ctx == nil {
94 return nil, errors.New("tls client failed")
95 }
96 if C.tls_configure(ctx, sslCfg) != 0 {
97 return nil, errors.New("tls configure failed")
98 }
99 return &TLS{
100 cfg: config,
101 ctx: ctx,
102 }, nil
103}
104
105// Error returns the error message from the TLS context.
106func (t *TLS) Error() string {
107 if msg := C.tls_error(t.ctx); msg != nil {
108 return C.GoString(msg)
109 }
110 return ""
111}
112
113// Connect attempts to establish an TLS connection to the specified host on
114// the given port. The host may optionally contain a colon separated port
115// value if the port string is specified as an empty string.
116func (t *TLS) Connect(host, port string) error {
117 h := C.CString(host)
118 var p *C.char
119 if port != "" {
120 p = C.CString(port)
121 }
122 defer C.free(unsafe.Pointer(h))
123 defer C.free(unsafe.Pointer(p))
124 if C.tls_connect(t.ctx, h, p) != 0 {
125 return fmt.Errorf("connect failed: %v", t.Error())
126 }
127 return nil
128}
129
130// Read reads data the TLS connection into the given buffer.
131func (t *TLS) Read(buf []byte) (int, error) {
132 var inlen C.size_t
133 if C.tls_read(t.ctx, unsafe.Pointer(&buf[0]), C.size_t(len(buf)), (*C.size_t)(unsafe.Pointer(&inlen))) != 0 {
134 return -1, fmt.Errorf("read failed: %v", t.Error())
135 }
136 return int(inlen), nil
137}
138
139// Write writes the given data to the TLS connection.
140func (t *TLS) Write(buf []byte) (int, error) {
141 var outlen C.size_t
142 p := C.CString(string(buf))
143 defer C.free(unsafe.Pointer(p))
144 if C.tls_write(t.ctx, unsafe.Pointer(p), C.size_t(len(buf)), (*C.size_t)(unsafe.Pointer(&outlen))) != 0 {
145 return -1, fmt.Errorf("write failed: %v", t.Error())
146 }
147 return int(outlen), nil
148}
149
150// Close closes the TLS connection.
151func (t *TLS) Close() error {
152 if C.tls_close(t.ctx) != 0 {
153 return fmt.Errorf("close failed: %v", t.Error())
154 }
155 return nil
156}
157
158// Free frees resources associated with the TLS context.
159func (t *TLS) Free() {
160 if t.ctx == nil {
161 return
162 }
163 C.tls_free(t.ctx)
164 t.ctx = nil
165}