@@ -3,6 +3,7 @@ package msspi
3
3
/*
4
4
#cgo windows LDFLAGS: -Lmsspi/build_linux -lmsspi -lstdc++ -lcrypt32
5
5
#cgo linux LDFLAGS: -Lmsspi/build_linux -lmsspi-capix -lstdc++ -ldl
6
+ #define NO_MSSPI_CERT
6
7
#include "msspi/src/msspi.h"
7
8
extern int cgo_msspi_read( void * goPointer, void * buf, int len );
8
9
extern int cgo_msspi_write( void * goPointer, void * buf, int len );
@@ -13,46 +14,45 @@ MSSPI_HANDLE cgo_msspi_open( void * goPointer ) {
13
14
import "C"
14
15
15
16
import (
16
- "crypto/tls"
17
- "io"
17
+ "errors"
18
18
"net"
19
19
"runtime"
20
- "sync"
21
20
"unsafe"
22
21
23
- "github.com/mattn/ go-pointer"
22
+ "go-pointer"
24
23
)
25
24
25
+ const ByDefault = true
26
+
27
+ //const ByDefault = false
28
+
26
29
// Conn with MSSPI
27
- type Conn struct {
28
- conn net.Conn
29
- tls * tls.Conn
30
- // MSSPI
30
+ type Handler struct {
31
+ conn * net.Conn
31
32
handle C.MSSPI_HANDLE
32
33
rerr error
33
34
werr error
34
35
isClient bool
35
36
goPointer unsafe.Pointer
36
- mu sync.Mutex
37
37
}
38
38
39
- func (c * Conn ) error () (err error ) {
40
- state := C .msspi_state (c .handle )
41
- if state & C .MSSPI_ERROR != 0 || state & (C .MSSPI_SENT_SHUTDOWN | C .MSSPI_RECEIVED_SHUTDOWN ) != 0 {
42
- err = io .EOF
43
- }
44
- return nil
39
+ func (c * Handler ) Read (b []byte ) (int , error ) {
40
+ n := (int )(C .msspi_read (c .handle , unsafe .Pointer (& b [0 ]), C .int (len (b ))))
41
+ return n , c .rerr
45
42
}
46
43
47
- func (c * Conn ) Read (b []byte ) (int , error ) {
48
- n := (int )(C .msspi_read (c .handle , unsafe .Pointer (& b [0 ]), C .int (len (b ))))
49
- if n > 0 {
50
- return n , nil
44
+ func (c * Handler ) State (val int ) bool {
45
+ state := C .msspi_state (c .handle )
46
+ if val == 1 {
47
+ return state & C .MSSPI_ERROR != 0
48
+ }
49
+ if val == 2 {
50
+ return state & (C .MSSPI_SENT_SHUTDOWN | C .MSSPI_RECEIVED_SHUTDOWN ) != 0
51
51
}
52
- return 0 , c . error ()
52
+ return false
53
53
}
54
54
55
- func (c * Conn ) Write (b []byte ) (int , error ) {
55
+ func (c * Handler ) Write (b []byte ) (int , error ) {
56
56
len := len (b )
57
57
sent := 0
58
58
for len > 0 {
@@ -63,47 +63,185 @@ func (c *Conn) Write(b []byte) (int, error) {
63
63
continue
64
64
}
65
65
66
- return sent , c .error ()
66
+ break
67
+ }
68
+
69
+ return sent , c .werr
70
+ }
71
+
72
+ func (h * Handler ) VersionTLS () uint16 {
73
+ info := C .msspi_get_cipherinfo (h .handle )
74
+ return uint16 (info .dwProtocol )
75
+ }
76
+
77
+ func (h * Handler ) CipherSuite () uint16 {
78
+ info := C .msspi_get_cipherinfo (h .handle )
79
+ return uint16 (info .dwCipherSuite )
80
+ }
81
+
82
+ func (c * Handler ) PeerCertificates () (certificates [][]byte ) {
83
+ count := C .size_t (0 )
84
+
85
+ if 0 == C .msspi_get_peercerts (c .handle , nil , nil , & count ) {
86
+ return nil
87
+ }
88
+
89
+ gocount := int (count )
90
+ bufs := make ([]* C.char , count )
91
+ lens := make ([]C.int , count )
92
+
93
+ if 0 == C .msspi_get_peercerts (c .handle , & bufs [0 ], & lens [0 ], & count ) {
94
+ return nil
95
+ }
96
+
97
+ for i := 0 ; i < gocount ; i ++ {
98
+ certificates = append (certificates , C .GoBytes (unsafe .Pointer (bufs [i ]), lens [i ]))
99
+ }
100
+
101
+ return certificates
102
+ }
103
+
104
+ func (c * Handler ) VerifiedChains () (certificates [][]byte ) {
105
+ if C .MSSPI_VERIFY_OK != C .msspi_verify (c .handle ) {
106
+ return nil
107
+ }
108
+
109
+ count := C .size_t (0 )
110
+
111
+ if 0 == C .msspi_get_peerchain (c .handle , 0 , nil , nil , & count ) {
112
+ return nil
113
+ }
114
+
115
+ gocount := int (count )
116
+ bufs := make ([]* C.char , count )
117
+ lens := make ([]C.int , count )
118
+
119
+ if 0 == C .msspi_get_peerchain (c .handle , 0 , & bufs [0 ], & lens [0 ], & count ) {
120
+ return nil
121
+ }
122
+
123
+ for i := 0 ; i < gocount ; i ++ {
124
+ certificates = append (certificates , C .GoBytes (unsafe .Pointer (bufs [i ]), lens [i ]))
125
+ }
126
+
127
+ return certificates
128
+ }
129
+
130
+ func (c * Handler ) Handshake () error {
131
+ n := - 1
132
+ for n < 0 {
133
+ if c .isClient {
134
+ n = (int )(C .msspi_connect (c .handle ))
135
+ } else {
136
+ n = (int )(C .msspi_accept (c .handle ))
137
+ }
138
+ }
139
+
140
+ if n == 1 {
141
+ return nil
142
+ }
143
+
144
+ if c .rerr != nil {
145
+ return c .rerr
67
146
}
68
- return sent , nil
147
+ if c .werr != nil {
148
+ return c .werr
149
+ }
150
+ return net .ErrClosed
69
151
}
70
152
71
153
// Close with MSSPI
72
- func (c * Conn ) Close () (err error ) {
154
+ func (c * Handler ) Close () (err error ) {
73
155
if c .handle != nil {
74
156
C .msspi_shutdown (c .handle )
157
+ }
158
+
159
+ if c .goPointer != nil {
75
160
pointer .Unref (c .goPointer )
161
+ c .goPointer = nil
76
162
}
77
- return c .conn .Close ()
163
+
164
+ return (* c .conn ).Close ()
165
+ }
166
+
167
+ // Shutdown with MSSPI
168
+ func (c * Handler ) Shutdown () (err error ) {
169
+ if c .handle != nil {
170
+ C .msspi_shutdown (c .handle )
171
+ }
172
+
173
+ if ! c .State (1 ) && c .State (2 ) {
174
+ return nil
175
+ }
176
+
177
+ return net .ErrClosed
78
178
}
79
179
80
180
// Finalizer with MSSPI
81
- func (c * Conn ) Finalizer () {
181
+ func (c * Handler ) Finalizer () {
82
182
if c .handle != nil {
83
183
C .msspi_close (c .handle )
184
+ c .handle = nil
84
185
}
85
186
}
86
187
87
188
// Client with MSSPI
88
- func Client (conn net.Conn , config * tls. Config ) * Conn {
89
- c : = & Conn {conn : conn , isClient : true }
90
- c . tls = tls . Client ( conn , config )
189
+ func Client (conn * net.Conn , CertificateBytes [][] byte , hostname string ) ( c * Handler , err error ) {
190
+ c = & Handler {conn : conn , isClient : true }
191
+ runtime . SetFinalizer ( c , ( * Handler ). Finalizer )
91
192
92
193
c .goPointer = pointer .Save (c )
93
194
c .handle = C .cgo_msspi_open (c .goPointer )
94
195
95
- if c .handle != nil {
96
- C .msspi_set_client (c .handle )
97
- runtime .SetFinalizer (c , (* Conn ).Finalizer )
98
- } else {
99
- pointer .Unref (c .goPointer )
196
+ if c .handle == nil {
197
+ return nil , errors .New ("Client msspi_open() failed" )
100
198
}
101
- return c
199
+
200
+ C .msspi_set_client (c .handle )
201
+
202
+ if hostname != "" {
203
+ hostnameBytes := []byte (hostname )
204
+ hostnameBytes = append (hostnameBytes , 0 )
205
+ C .msspi_set_hostname (c .handle , (* C .char )(unsafe .Pointer (& hostnameBytes [0 ])))
206
+ }
207
+
208
+ for _ , cbs := range CertificateBytes {
209
+ ok := int (C .msspi_add_mycert (c .handle , (* C .char )(unsafe .Pointer (& cbs [0 ])), C .int (len (cbs ))))
210
+ if ok != 1 {
211
+ return nil , errors .New ("Client msspi_add_mycert() failed" )
212
+ }
213
+ break
214
+ }
215
+
216
+ return c , nil
102
217
}
103
218
104
- // Server with MSSPI (not implemented)
105
- func Server (conn net.Conn , config * tls.Config ) * Conn {
106
- c := & Conn {conn : conn , isClient : false }
107
- c .tls = tls .Server (conn , config )
108
- return nil
219
+ // Server with MSSPI
220
+ func Server (conn * net.Conn , CertificateBytes [][]byte , clientAuth bool ) (c * Handler , err error ) {
221
+ c = & Handler {conn : conn , isClient : false }
222
+ runtime .SetFinalizer (c , (* Handler ).Finalizer )
223
+
224
+ c .goPointer = pointer .Save (c )
225
+ c .handle = C .cgo_msspi_open (c .goPointer )
226
+
227
+ if c .handle == nil {
228
+ return nil , errors .New ("Server msspi_open() failed" )
229
+ }
230
+
231
+ if clientAuth {
232
+ C .msspi_set_peerauth (c .handle , 1 )
233
+ }
234
+
235
+ srv := []byte ("srv" )
236
+ C .msspi_set_hostname (c .handle , (* C .char )(unsafe .Pointer (& srv [0 ])))
237
+
238
+ for _ , cbs := range CertificateBytes {
239
+ ok := int (C .msspi_add_mycert (c .handle , (* C .char )(unsafe .Pointer (& cbs [0 ])), C .int (len (cbs ))))
240
+ if ok != 1 {
241
+ return nil , errors .New ("Server msspi_add_mycert() failed" )
242
+ }
243
+ break
244
+ }
245
+
246
+ return c , nil
109
247
}
0 commit comments