summaryrefslogtreecommitdiff
path: root/src/regress/lib/libtls
diff options
context:
space:
mode:
Diffstat (limited to 'src/regress/lib/libtls')
-rw-r--r--src/regress/lib/libtls/Makefile12
-rw-r--r--src/regress/lib/libtls/Makefile.inc2
-rw-r--r--src/regress/lib/libtls/config/Makefile10
-rw-r--r--src/regress/lib/libtls/config/configtest.c171
-rw-r--r--src/regress/lib/libtls/gotls/Makefile16
-rw-r--r--src/regress/lib/libtls/gotls/tls.go341
-rw-r--r--src/regress/lib/libtls/gotls/tls_test.go421
-rw-r--r--src/regress/lib/libtls/keypair/Makefile20
-rw-r--r--src/regress/lib/libtls/keypair/keypairtest.c211
-rw-r--r--src/regress/lib/libtls/tls/Makefile19
-rw-r--r--src/regress/lib/libtls/tls/tlstest.c450
-rw-r--r--src/regress/lib/libtls/verify/Makefile10
-rw-r--r--src/regress/lib/libtls/verify/verifytest.c524
13 files changed, 0 insertions, 2207 deletions
diff --git a/src/regress/lib/libtls/Makefile b/src/regress/lib/libtls/Makefile
deleted file mode 100644
index f522605a90..0000000000
--- a/src/regress/lib/libtls/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
1# $OpenBSD: Makefile,v 1.5 2018/02/08 10:06:52 jsing Exp $
2
3SUBDIR= \
4 config \
5 keypair \
6 gotls \
7 tls \
8 verify
9
10install:
11
12.include <bsd.subdir.mk>
diff --git a/src/regress/lib/libtls/Makefile.inc b/src/regress/lib/libtls/Makefile.inc
deleted file mode 100644
index e693da81b4..0000000000
--- a/src/regress/lib/libtls/Makefile.inc
+++ /dev/null
@@ -1,2 +0,0 @@
1# Use this variable when the test needs internal symbols from libtls
2TLS_INT= -Wl,-Bstatic -ltls -Wl,-Bdynamic
diff --git a/src/regress/lib/libtls/config/Makefile b/src/regress/lib/libtls/config/Makefile
deleted file mode 100644
index 02c36c5d93..0000000000
--- a/src/regress/lib/libtls/config/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
1# $OpenBSD: Makefile,v 1.2 2018/02/08 10:05:43 jsing Exp $
2
3PROG= configtest
4LDADD= -lcrypto -lssl -ltls
5DPADD= ${LIBCRYPTO} ${LIBSSL} ${LIBTLS}
6
7WARNINGS= Yes
8CFLAGS+= -DLIBRESSL_INTERNAL -Wall -Wundef -Werror
9
10.include <bsd.regress.mk>
diff --git a/src/regress/lib/libtls/config/configtest.c b/src/regress/lib/libtls/config/configtest.c
deleted file mode 100644
index 61474aa85c..0000000000
--- a/src/regress/lib/libtls/config/configtest.c
+++ /dev/null
@@ -1,171 +0,0 @@
1/* $OpenBSD: configtest.c,v 1.1 2017/12/09 16:43:09 jsing Exp $ */
2/*
3 * Copyright (c) 2017 Joel Sing <jsing@openbsd.org>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#include <err.h>
19#include <stdio.h>
20#include <stdlib.h>
21
22#include <tls.h>
23
24struct parse_protocols_test {
25 const char *protostr;
26 int want_return;
27 uint32_t want_protocols;
28};
29
30struct parse_protocols_test parse_protocols_tests[] = {
31 {
32 .protostr = NULL,
33 .want_return = 0,
34 .want_protocols = TLS_PROTOCOLS_DEFAULT,
35 },
36 {
37 .protostr = "default",
38 .want_return = 0,
39 .want_protocols = TLS_PROTOCOLS_DEFAULT,
40 },
41 {
42 .protostr = "secure",
43 .want_return = 0,
44 .want_protocols = TLS_PROTOCOLS_DEFAULT,
45 },
46 {
47 .protostr = "all",
48 .want_return = 0,
49 .want_protocols = TLS_PROTOCOLS_ALL,
50 },
51 {
52 .protostr = "tlsv1",
53 .want_return = 0,
54 .want_protocols = TLS_PROTOCOL_TLSv1,
55 },
56 {
57 .protostr = "tlsv1.2",
58 .want_return = 0,
59 .want_protocols = TLS_PROTOCOL_TLSv1_2,
60 },
61 {
62 .protostr = "",
63 .want_return = -1,
64 .want_protocols = 0,
65 },
66 {
67 .protostr = "tlsv1.0:tlsv1.1:tlsv1.2",
68 .want_return = 0,
69 .want_protocols = TLS_PROTOCOL_TLSv1_0 | TLS_PROTOCOL_TLSv1_1 |
70 TLS_PROTOCOL_TLSv1_2,
71 },
72 {
73 .protostr = "tlsv1.0,tlsv1.1,tlsv1.2",
74 .want_return = 0,
75 .want_protocols = TLS_PROTOCOL_TLSv1_0 | TLS_PROTOCOL_TLSv1_1 |
76 TLS_PROTOCOL_TLSv1_2,
77 },
78 {
79 .protostr = "tlsv1.1,tlsv1.2,tlsv1.0",
80 .want_return = 0,
81 .want_protocols = TLS_PROTOCOL_TLSv1_0 | TLS_PROTOCOL_TLSv1_1 |
82 TLS_PROTOCOL_TLSv1_2,
83 },
84 {
85 .protostr = "tlsv1.1,tlsv1.2,tlsv1.1",
86 .want_return = 0,
87 .want_protocols = TLS_PROTOCOL_TLSv1_1 | TLS_PROTOCOL_TLSv1_2,
88 },
89 {
90 .protostr = "tlsv1.1,tlsv1.2,!tlsv1.1",
91 .want_return = 0,
92 .want_protocols = TLS_PROTOCOL_TLSv1_2,
93 },
94 {
95 .protostr = "unknown",
96 .want_return = -1,
97 .want_protocols = 0,
98 },
99 {
100 .protostr = "all,!unknown",
101 .want_return = -1,
102 .want_protocols = 0,
103 },
104 {
105 .protostr = "sslv3,tlsv1.0,tlsv1.1,tlsv1.2",
106 .want_return = -1,
107 .want_protocols = 0,
108 },
109 {
110 .protostr = "all,!tlsv1.0",
111 .want_return = 0,
112 .want_protocols = TLS_PROTOCOL_TLSv1_1 | TLS_PROTOCOL_TLSv1_2,
113 },
114 {
115 .protostr = "!tlsv1.0",
116 .want_return = 0,
117 .want_protocols = TLS_PROTOCOL_TLSv1_1 | TLS_PROTOCOL_TLSv1_2,
118 },
119 {
120 .protostr = "!tlsv1.0,!tlsv1.1",
121 .want_return = 0,
122 .want_protocols = TLS_PROTOCOL_TLSv1_2,
123 },
124 {
125 .protostr = "!tlsv1.0,!tlsv1.1,tlsv1.2",
126 .want_return = 0,
127 .want_protocols = TLS_PROTOCOL_TLSv1_2,
128 },
129};
130
131#define N_PARSE_PROTOCOLS_TESTS \
132 (sizeof(parse_protocols_tests) / sizeof(*parse_protocols_tests))
133
134static int
135do_parse_protocols_test(int test_no, struct parse_protocols_test *ppt)
136{
137 uint32_t protocols = 0;
138 int failed = 1;
139 int rv;
140
141 rv = tls_config_parse_protocols(&protocols, ppt->protostr);
142 if (rv != ppt->want_return) {
143 fprintf(stderr, "FAIL: test %i - tls_config_parse_protocols() "
144 "returned %i, want %i\n", test_no, rv, ppt->want_return);
145 goto done;
146 }
147 if (protocols != ppt->want_protocols) {
148 fprintf(stderr, "FAIL: test %i - got protocols 0x%x, "
149 "want 0x%x\n", test_no, protocols, ppt->want_protocols);
150 goto done;
151 }
152
153 failed = 0;
154
155 done:
156 return (failed);
157}
158
159int
160main(int argc, char **argv)
161{
162 int failed = 0;
163 size_t i;
164
165 tls_init();
166
167 for (i = 0; i < N_PARSE_PROTOCOLS_TESTS; i++)
168 failed += do_parse_protocols_test(i, &parse_protocols_tests[i]);
169
170 return (failed);
171}
diff --git a/src/regress/lib/libtls/gotls/Makefile b/src/regress/lib/libtls/gotls/Makefile
deleted file mode 100644
index 404aa79caa..0000000000
--- a/src/regress/lib/libtls/gotls/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
1# $OpenBSD: Makefile,v 1.2 2016/09/02 21:30:34 bluhm Exp $
2
3GO_VERSION != sh -c "(go version) 2>/dev/null || true"
4
5.if empty(GO_VERSION)
6regress:
7 @echo package go is required for this regress
8 @echo SKIPPED
9.endif
10
11REGRESS_TARGETS=regress-gotls
12
13regress-gotls:
14 cd ${.CURDIR} && go test -test.v .
15
16.include <bsd.regress.mk>
diff --git a/src/regress/lib/libtls/gotls/tls.go b/src/regress/lib/libtls/gotls/tls.go
deleted file mode 100644
index be75e71f4f..0000000000
--- a/src/regress/lib/libtls/gotls/tls.go
+++ /dev/null
@@ -1,341 +0,0 @@
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 "time"
19 "unsafe"
20)
21
22var (
23 errWantPollIn = errors.New("want poll in")
24 errWantPollOut = errors.New("want poll out")
25)
26
27// ProtocolVersion represents a TLS protocol version.
28type ProtocolVersion uint32
29
30// String returns the string representation of a protocol version.
31func (pv ProtocolVersion) String() string {
32 name, ok := protocolNames[pv]
33 if !ok {
34 return fmt.Sprintf("unknown protocol version %x", uint32(pv))
35 }
36 return name
37}
38
39const (
40 ProtocolTLSv10 ProtocolVersion = C.TLS_PROTOCOL_TLSv1_0
41 ProtocolTLSv11 ProtocolVersion = C.TLS_PROTOCOL_TLSv1_1
42 ProtocolTLSv12 ProtocolVersion = C.TLS_PROTOCOL_TLSv1_2
43 ProtocolsAll ProtocolVersion = C.TLS_PROTOCOLS_ALL
44)
45
46var protocolNames = map[ProtocolVersion]string{
47 ProtocolTLSv10: "TLSv1",
48 ProtocolTLSv11: "TLSv1.1",
49 ProtocolTLSv12: "TLSv1.2",
50 ProtocolsAll: "all",
51}
52
53// ProtocolVersionFromString returns the protocol version with the given name.
54func ProtocolVersionFromString(version string) (ProtocolVersion, error) {
55 for proto, name := range protocolNames {
56 if version == name {
57 return proto, nil
58 }
59 }
60 return 0, fmt.Errorf("unknown protocol version %q", version)
61}
62
63// TLSConfig provides configuration options for a TLS context.
64type TLSConfig struct {
65 tlsCfg *C.struct_tls_config
66}
67
68// TLS encapsulates the TLS context.
69type TLS struct {
70 cfg *TLSConfig
71 ctx *C.struct_tls
72}
73
74// Init initialises the TLS library.
75func Init() error {
76 if C.tls_init() != 0 {
77 return errors.New("initialisation failed")
78 }
79 return nil
80}
81
82// NewConfig returns a new TLS configuration.
83func NewConfig() (*TLSConfig, error) {
84 cfg := C.tls_config_new()
85 if cfg == nil {
86 return nil, errors.New("failed to allocate config")
87 }
88 return &TLSConfig{
89 tlsCfg: cfg,
90 }, nil
91}
92
93// Error returns the error message from the TLS configuration.
94func (c *TLSConfig) Error() error {
95 if msg := C.tls_config_error(c.tlsCfg); msg != nil {
96 return errors.New(C.GoString(msg))
97 }
98 return errors.New("unknown error")
99}
100
101// SetCAFile sets the CA file to be used for connections.
102func (c *TLSConfig) SetCAFile(filename string) error {
103 caFile := C.CString(filename)
104 defer C.free(unsafe.Pointer(caFile))
105 if C.tls_config_set_ca_file(c.tlsCfg, caFile) != 0 {
106 return c.Error()
107 }
108 return nil
109}
110
111// SetCiphers sets the cipher suites enabled for the connection.
112func (c *TLSConfig) SetCiphers(ciphers string) error {
113 cipherStr := C.CString(ciphers)
114 defer C.free(unsafe.Pointer(cipherStr))
115 if C.tls_config_set_ciphers(c.tlsCfg, cipherStr) != 0 {
116 return c.Error()
117 }
118 return nil
119}
120
121// SetProtocols sets the protocol versions enabled for the connection.
122func (c *TLSConfig) SetProtocols(proto ProtocolVersion) error {
123 if C.tls_config_set_protocols(c.tlsCfg, C.uint32_t(proto)) != 0 {
124 return c.Error()
125 }
126 return nil
127}
128
129// InsecureNoVerifyCert disables certificate verification for the connection.
130func (c *TLSConfig) InsecureNoVerifyCert() {
131 C.tls_config_insecure_noverifycert(c.tlsCfg)
132}
133
134// InsecureNoVerifyName disables server name verification for the connection.
135func (c *TLSConfig) InsecureNoVerifyName() {
136 C.tls_config_insecure_noverifyname(c.tlsCfg)
137}
138
139// SetSecure enables verification for the connection.
140func (c *TLSConfig) SetVerify() {
141 C.tls_config_verify(c.tlsCfg)
142}
143
144// Free frees resources associated with the TLS configuration.
145func (c *TLSConfig) Free() {
146 if c.tlsCfg == nil {
147 return
148 }
149 C.tls_config_free(c.tlsCfg)
150 c.tlsCfg = nil
151}
152
153// NewClient returns a new TLS client context, using the optional configuration.
154// If no configuration is specified the default configuration will be used.
155func NewClient(config *TLSConfig) (*TLS, error) {
156 var sslCfg *C.struct_tls_config
157 if config != nil {
158 sslCfg = config.tlsCfg
159 }
160 ctx := C.tls_client()
161 if ctx == nil {
162 return nil, errors.New("tls client failed")
163 }
164 if C.tls_configure(ctx, sslCfg) != 0 {
165 return nil, errors.New("tls configure failed")
166 }
167 return &TLS{
168 cfg: config,
169 ctx: ctx,
170 }, nil
171}
172
173// Error returns the error message from the TLS context.
174func (t *TLS) Error() error {
175 if msg := C.tls_error(t.ctx); msg != nil {
176 return errors.New(C.GoString(msg))
177 }
178 return errors.New("unknown error")
179}
180
181// PeerCertProvided returns whether the peer provided a certificate.
182func (t *TLS) PeerCertProvided() bool {
183 return C.tls_peer_cert_provided(t.ctx) == 1
184}
185
186// PeerCertContainsName checks whether the peer certificate contains
187// the specified name.
188func (t *TLS) PeerCertContainsName(name string) bool {
189 n := C.CString(name)
190 defer C.free(unsafe.Pointer(n))
191 return C.tls_peer_cert_contains_name(t.ctx, n) == 1
192}
193
194// PeerCertIssuer returns the issuer of the peer certificate.
195func (t *TLS) PeerCertIssuer() (string, error) {
196 issuer := C.tls_peer_cert_issuer(t.ctx)
197 if issuer == nil {
198 return "", errors.New("no issuer returned")
199 }
200 return C.GoString(issuer), nil
201}
202
203// PeerCertSubject returns the subject of the peer certificate.
204func (t *TLS) PeerCertSubject() (string, error) {
205 subject := C.tls_peer_cert_subject(t.ctx)
206 if subject == nil {
207 return "", errors.New("no subject returned")
208 }
209 return C.GoString(subject), nil
210}
211
212// PeerCertHash returns a hash of the peer certificate.
213func (t *TLS) PeerCertHash() (string, error) {
214 hash := C.tls_peer_cert_hash(t.ctx)
215 if hash == nil {
216 return "", errors.New("no hash returned")
217 }
218 return C.GoString(hash), nil
219}
220
221// PeerCertNotBefore returns the notBefore time from the peer
222// certificate.
223func (t *TLS) PeerCertNotBefore() (time.Time, error) {
224 notBefore := C.tls_peer_cert_notbefore(t.ctx)
225 if notBefore == -1 {
226 return time.Time{}, errors.New("no notBefore time returned")
227 }
228 return time.Unix(int64(notBefore), 0), nil
229}
230
231// PeerCertNotAfter returns the notAfter time from the peer
232// certificate.
233func (t *TLS) PeerCertNotAfter() (time.Time, error) {
234 notAfter := C.tls_peer_cert_notafter(t.ctx)
235 if notAfter == -1 {
236 return time.Time{}, errors.New("no notAfter time")
237 }
238 return time.Unix(int64(notAfter), 0), nil
239}
240
241// ConnVersion returns the protocol version of the connection.
242func (t *TLS) ConnVersion() (ProtocolVersion, error) {
243 ver := C.tls_conn_version(t.ctx)
244 if ver == nil {
245 return 0, errors.New("no connection version")
246 }
247 return ProtocolVersionFromString(C.GoString(ver))
248}
249
250// ConnCipher returns the cipher suite used for the connection.
251func (t *TLS) ConnCipher() (string, error) {
252 cipher := C.tls_conn_cipher(t.ctx)
253 if cipher == nil {
254 return "", errors.New("no connection cipher")
255 }
256 return C.GoString(cipher), nil
257}
258
259// Connect attempts to establish an TLS connection to the specified host on
260// the given port. The host may optionally contain a colon separated port
261// value if the port string is specified as an empty string.
262func (t *TLS) Connect(host, port string) error {
263 h := C.CString(host)
264 var p *C.char
265 if port != "" {
266 p = C.CString(port)
267 }
268 defer C.free(unsafe.Pointer(h))
269 defer C.free(unsafe.Pointer(p))
270 if C.tls_connect(t.ctx, h, p) != 0 {
271 return t.Error()
272 }
273 return nil
274}
275
276// Handshake attempts to complete the TLS handshake.
277func (t *TLS) Handshake() error {
278 ret := C.tls_handshake(t.ctx)
279 switch {
280 case ret == C.TLS_WANT_POLLIN:
281 return errWantPollIn
282 case ret == C.TLS_WANT_POLLOUT:
283 return errWantPollOut
284 case ret != 0:
285 return t.Error()
286 }
287 return nil
288}
289
290// Read reads data the TLS connection into the given buffer.
291func (t *TLS) Read(buf []byte) (int, error) {
292 ret := C.tls_read(t.ctx, unsafe.Pointer(&buf[0]), C.size_t(len(buf)))
293 switch {
294 case ret == C.TLS_WANT_POLLIN:
295 return -1, errWantPollIn
296 case ret == C.TLS_WANT_POLLOUT:
297 return -1, errWantPollOut
298 case ret < 0:
299 return -1, t.Error()
300 }
301 return int(ret), nil
302}
303
304// Write writes the given data to the TLS connection.
305func (t *TLS) Write(buf []byte) (int, error) {
306 p := C.CString(string(buf))
307 defer C.free(unsafe.Pointer(p))
308 ret := C.tls_write(t.ctx, unsafe.Pointer(p), C.size_t(len(buf)))
309 switch {
310 case ret == C.TLS_WANT_POLLIN:
311 return -1, errWantPollIn
312 case ret == C.TLS_WANT_POLLOUT:
313 return -1, errWantPollOut
314 case ret < 0:
315 return -1, t.Error()
316 }
317 return int(ret), nil
318}
319
320// Close closes the TLS connection.
321func (t *TLS) Close() error {
322 ret := C.tls_close(t.ctx)
323 switch {
324 case ret == C.TLS_WANT_POLLIN:
325 return errWantPollIn
326 case ret == C.TLS_WANT_POLLOUT:
327 return errWantPollOut
328 case ret != 0:
329 return t.Error()
330 }
331 return nil
332}
333
334// Free frees resources associated with the TLS context.
335func (t *TLS) Free() {
336 if t.ctx == nil {
337 return
338 }
339 C.tls_free(t.ctx)
340 t.ctx = nil
341}
diff --git a/src/regress/lib/libtls/gotls/tls_test.go b/src/regress/lib/libtls/gotls/tls_test.go
deleted file mode 100644
index 077dd86e82..0000000000
--- a/src/regress/lib/libtls/gotls/tls_test.go
+++ /dev/null
@@ -1,421 +0,0 @@
1package tls
2
3import (
4 "crypto/tls"
5 "encoding/pem"
6 "fmt"
7 "io/ioutil"
8 "net/http"
9 "net/http/httptest"
10 "net/url"
11 "os"
12 "strings"
13 "testing"
14 "time"
15)
16
17const (
18 httpContent = "Hello, TLS!"
19
20 certHash = "SHA256:448f628a8a65aa18560e53a80c53acb38c51b427df0334082349141147dc9bf6"
21)
22
23var (
24 certNotBefore = time.Unix(0, 0)
25 certNotAfter = certNotBefore.Add(1000000 * time.Hour)
26)
27
28type handshakeError string
29
30func (he handshakeError) Error() string {
31 return string(he)
32}
33
34// createCAFile writes a PEM encoded version of the certificate out to a
35// temporary file, for use by libtls.
36func createCAFile(cert []byte) (string, error) {
37 f, err := ioutil.TempFile("", "tls")
38 if err != nil {
39 return "", fmt.Errorf("failed to create file: %v", err)
40 }
41 defer f.Close()
42 block := &pem.Block{
43 Type: "CERTIFICATE",
44 Bytes: cert,
45 }
46 if err := pem.Encode(f, block); err != nil {
47 return "", fmt.Errorf("failed to encode certificate: %v", err)
48 }
49 return f.Name(), nil
50}
51
52func newTestServer(tlsCfg *tls.Config) (*httptest.Server, *url.URL, string, error) {
53 ts := httptest.NewUnstartedServer(
54 http.HandlerFunc(
55 func(w http.ResponseWriter, r *http.Request) {
56 fmt.Fprintln(w, httpContent)
57 },
58 ),
59 )
60 ts.TLS = tlsCfg
61 ts.StartTLS()
62
63 u, err := url.Parse(ts.URL)
64 if err != nil {
65 return nil, nil, "", fmt.Errorf("failed to parse URL %q: %v", ts.URL, err)
66 }
67
68 caFile, err := createCAFile(ts.TLS.Certificates[0].Certificate[0])
69 if err != nil {
70 return nil, nil, "", fmt.Errorf("failed to create CA file: %v", err)
71 }
72
73 return ts, u, caFile, nil
74}
75
76func handshakeVersionTest(tlsCfg *tls.Config) (ProtocolVersion, error) {
77 ts, u, caFile, err := newTestServer(tlsCfg)
78 if err != nil {
79 return 0, fmt.Errorf("failed to start test server: %v", err)
80 }
81 defer os.Remove(caFile)
82 defer ts.Close()
83
84 if err := Init(); err != nil {
85 return 0, err
86 }
87
88 cfg, err := NewConfig()
89 if err != nil {
90 return 0, err
91 }
92 defer cfg.Free()
93 if err := cfg.SetCAFile(caFile); err != nil {
94 return 0, err
95 }
96 if err := cfg.SetCiphers("compat"); err != nil {
97 return 0, err
98 }
99 if err := cfg.SetProtocols(ProtocolsAll); err != nil {
100 return 0, err
101 }
102
103 tls, err := NewClient(cfg)
104 if err != nil {
105 return 0, err
106 }
107 defer tls.Free()
108
109 if err := tls.Connect(u.Host, ""); err != nil {
110 return 0, err
111 }
112 if err := tls.Handshake(); err != nil {
113 return 0, handshakeError(err.Error())
114 }
115 version, err := tls.ConnVersion()
116 if err != nil {
117 return 0, err
118 }
119 if err := tls.Close(); err != nil {
120 return 0, err
121 }
122 return version, nil
123}
124
125func TestTLSBasic(t *testing.T) {
126 ts, u, caFile, err := newTestServer(nil)
127 if err != nil {
128 t.Fatalf("Failed to start test server: %v", err)
129 }
130 defer os.Remove(caFile)
131 defer ts.Close()
132
133 if err := Init(); err != nil {
134 t.Fatal(err)
135 }
136
137 cfg, err := NewConfig()
138 if err != nil {
139 t.Fatal(err)
140 }
141 defer cfg.Free()
142 if err := cfg.SetCAFile(caFile); err != nil {
143 t.Fatal(err)
144 }
145
146 tls, err := NewClient(cfg)
147 if err != nil {
148 t.Fatal(err)
149 }
150 defer tls.Free()
151
152 t.Logf("Connecting to %s", u.Host)
153
154 if err := tls.Connect(u.Host, ""); err != nil {
155 t.Fatal(err)
156 }
157 defer func() {
158 if err := tls.Close(); err != nil {
159 t.Fatalf("Close failed: %v", err)
160 }
161 }()
162
163 n, err := tls.Write([]byte("GET / HTTP/1.0\n\n"))
164 if err != nil {
165 t.Fatal(err)
166 }
167 t.Logf("Wrote %d bytes...", n)
168
169 buf := make([]byte, 1024)
170 n, err = tls.Read(buf)
171 if err != nil {
172 t.Fatal(err)
173 }
174 t.Logf("Read %d bytes...", n)
175
176 if !strings.Contains(string(buf), httpContent) {
177 t.Errorf("Response does not contain %q", httpContent)
178 }
179}
180
181func TestTLSVersions(t *testing.T) {
182 tests := []struct {
183 minVersion uint16
184 maxVersion uint16
185 wantVersion ProtocolVersion
186 wantHandshakeErr bool
187 }{
188 {tls.VersionSSL30, tls.VersionTLS12, ProtocolTLSv12, false},
189 {tls.VersionTLS10, tls.VersionTLS12, ProtocolTLSv12, false},
190 {tls.VersionTLS11, tls.VersionTLS12, ProtocolTLSv12, false},
191 {tls.VersionSSL30, tls.VersionTLS11, ProtocolTLSv11, false},
192 {tls.VersionSSL30, tls.VersionTLS10, ProtocolTLSv10, false},
193 {tls.VersionSSL30, tls.VersionSSL30, 0, true},
194 {tls.VersionTLS10, tls.VersionTLS10, ProtocolTLSv10, false},
195 {tls.VersionTLS11, tls.VersionTLS11, ProtocolTLSv11, false},
196 {tls.VersionTLS12, tls.VersionTLS12, ProtocolTLSv12, false},
197 }
198 for i, test := range tests {
199 t.Logf("Testing handshake with protocols %x:%x", test.minVersion, test.maxVersion)
200 tlsCfg := &tls.Config{
201 MinVersion: test.minVersion,
202 MaxVersion: test.maxVersion,
203 }
204 version, err := handshakeVersionTest(tlsCfg)
205 switch {
206 case test.wantHandshakeErr && err == nil:
207 t.Errorf("Test %d - handshake %x:%x succeeded, want handshake error",
208 i, test.minVersion, test.maxVersion)
209 case test.wantHandshakeErr && err != nil:
210 if _, ok := err.(handshakeError); !ok {
211 t.Errorf("Test %d - handshake %x:%x; got unknown error, want handshake error: %v",
212 i, test.minVersion, test.maxVersion, err)
213 }
214 case !test.wantHandshakeErr && err != nil:
215 t.Errorf("Test %d - handshake %x:%x failed: %v", i, test.minVersion, test.maxVersion, err)
216 case !test.wantHandshakeErr && err == nil:
217 if got, want := version, test.wantVersion; got != want {
218 t.Errorf("Test %d - handshake %x:%x; got protocol version %v, want %v",
219 i, test.minVersion, test.maxVersion, got, want)
220 }
221 }
222 }
223}
224
225func TestTLSSingleByteReadWrite(t *testing.T) {
226 ts, u, caFile, err := newTestServer(nil)
227 if err != nil {
228 t.Fatalf("Failed to start test server: %v", err)
229 }
230 defer os.Remove(caFile)
231 defer ts.Close()
232
233 if err := Init(); err != nil {
234 t.Fatal(err)
235 }
236
237 cfg, err := NewConfig()
238 if err != nil {
239 t.Fatal(err)
240 }
241 defer cfg.Free()
242 if err := cfg.SetCAFile(caFile); err != nil {
243 t.Fatal(err)
244 }
245
246 tls, err := NewClient(cfg)
247 if err != nil {
248 t.Fatal(err)
249 }
250 defer tls.Free()
251
252 t.Logf("Connecting to %s", u.Host)
253
254 if err := tls.Connect(u.Host, ""); err != nil {
255 t.Fatal(err)
256 }
257 defer func() {
258 if err := tls.Close(); err != nil {
259 t.Fatalf("Close failed: %v", err)
260 }
261 }()
262
263 for _, b := range []byte("GET / HTTP/1.0\n\n") {
264 n, err := tls.Write([]byte{b})
265 if err != nil {
266 t.Fatal(err)
267 }
268 if n != 1 {
269 t.Fatalf("Wrote byte %v, got length %d, want 1", b, n)
270 }
271 }
272
273 var body []byte
274 for {
275 buf := make([]byte, 1)
276 n, err := tls.Read(buf)
277 if err != nil {
278 t.Fatal(err)
279 }
280 if n == 0 {
281 break
282 }
283 if n != 1 {
284 t.Fatalf("Read single byte, got length %d, want 1", n)
285 }
286 body = append(body, buf...)
287 }
288
289 if !strings.Contains(string(body), httpContent) {
290 t.Errorf("Response does not contain %q", httpContent)
291 }
292}
293
294func TestTLSInfo(t *testing.T) {
295 ts, u, caFile, err := newTestServer(nil)
296 if err != nil {
297 t.Fatalf("Failed to start test server: %v", err)
298 }
299 defer os.Remove(caFile)
300 defer ts.Close()
301
302 if err := Init(); err != nil {
303 t.Fatal(err)
304 }
305
306 cfg, err := NewConfig()
307 if err != nil {
308 t.Fatal(err)
309 }
310 defer cfg.Free()
311 if err := cfg.SetCAFile(caFile); err != nil {
312 t.Fatal(err)
313 }
314
315 tls, err := NewClient(cfg)
316 if err != nil {
317 t.Fatal(err)
318 }
319 defer tls.Free()
320
321 t.Logf("Connecting to %s", u.Host)
322
323 if err := tls.Connect(u.Host, ""); err != nil {
324 t.Fatal(err)
325 }
326 defer func() {
327 if err := tls.Close(); err != nil {
328 t.Fatalf("Close failed: %v", err)
329 }
330 }()
331
332 // All of these should fail since the handshake has not completed.
333 if _, err := tls.ConnVersion(); err == nil {
334 t.Error("ConnVersion() return nil error, want error")
335 }
336 if _, err := tls.ConnCipher(); err == nil {
337 t.Error("ConnCipher() return nil error, want error")
338 }
339
340 if got, want := tls.PeerCertProvided(), false; got != want {
341 t.Errorf("PeerCertProvided() = %v, want %v", got, want)
342 }
343 for _, name := range []string{"127.0.0.1", "::1", "example.com"} {
344 if got, want := tls.PeerCertContainsName(name), false; got != want {
345 t.Errorf("PeerCertContainsName(%q) = %v, want %v", name, got, want)
346 }
347 }
348
349 if _, err := tls.PeerCertIssuer(); err == nil {
350 t.Error("PeerCertIssuer() returned nil error, want error")
351 }
352 if _, err := tls.PeerCertSubject(); err == nil {
353 t.Error("PeerCertSubject() returned nil error, want error")
354 }
355 if _, err := tls.PeerCertHash(); err == nil {
356 t.Error("PeerCertHash() returned nil error, want error")
357 }
358 if _, err := tls.PeerCertNotBefore(); err == nil {
359 t.Error("PeerCertNotBefore() returned nil error, want error")
360 }
361 if _, err := tls.PeerCertNotAfter(); err == nil {
362 t.Error("PeerCertNotAfter() returned nil error, want error")
363 }
364
365 // Complete the handshake...
366 if err := tls.Handshake(); err != nil {
367 t.Fatalf("Handshake failed: %v", err)
368 }
369
370 if version, err := tls.ConnVersion(); err != nil {
371 t.Errorf("ConnVersion() return error: %v", err)
372 } else {
373 t.Logf("Protocol version: %v", version)
374 }
375 if cipher, err := tls.ConnCipher(); err != nil {
376 t.Errorf("ConnCipher() return error: %v", err)
377 } else {
378 t.Logf("Cipher: %v", cipher)
379 }
380
381 if got, want := tls.PeerCertProvided(), true; got != want {
382 t.Errorf("PeerCertProvided() = %v, want %v", got, want)
383 }
384 for _, name := range []string{"127.0.0.1", "::1", "example.com"} {
385 if got, want := tls.PeerCertContainsName(name), true; got != want {
386 t.Errorf("PeerCertContainsName(%q) = %v, want %v", name, got, want)
387 }
388 }
389
390 if issuer, err := tls.PeerCertIssuer(); err != nil {
391 t.Errorf("PeerCertIssuer() returned error: %v", err)
392 } else {
393 t.Logf("Issuer: %v", issuer)
394 }
395 if subject, err := tls.PeerCertSubject(); err != nil {
396 t.Errorf("PeerCertSubject() returned error: %v", err)
397 } else {
398 t.Logf("Subject: %v", subject)
399 }
400 if hash, err := tls.PeerCertHash(); err != nil {
401 t.Errorf("PeerCertHash() returned error: %v", err)
402 } else if hash != certHash {
403 t.Errorf("Got cert hash %q, want %q", hash, certHash)
404 } else {
405 t.Logf("Hash: %v", hash)
406 }
407 if notBefore, err := tls.PeerCertNotBefore(); err != nil {
408 t.Errorf("PeerCertNotBefore() returned error: %v", err)
409 } else if !certNotBefore.Equal(notBefore) {
410 t.Errorf("Got cert notBefore %v, want %v", notBefore.UTC(), certNotBefore.UTC())
411 } else {
412 t.Logf("NotBefore: %v", notBefore.UTC())
413 }
414 if notAfter, err := tls.PeerCertNotAfter(); err != nil {
415 t.Errorf("PeerCertNotAfter() returned error: %v", err)
416 } else if !certNotAfter.Equal(notAfter) {
417 t.Errorf("Got cert notAfter %v, want %v", notAfter.UTC(), certNotAfter.UTC())
418 } else {
419 t.Logf("NotAfter: %v", notAfter.UTC())
420 }
421}
diff --git a/src/regress/lib/libtls/keypair/Makefile b/src/regress/lib/libtls/keypair/Makefile
deleted file mode 100644
index d06109a26b..0000000000
--- a/src/regress/lib/libtls/keypair/Makefile
+++ /dev/null
@@ -1,20 +0,0 @@
1# $OpenBSD: Makefile,v 1.1 2018/02/08 10:06:52 jsing Exp $
2
3PROG= keypairtest
4LDADD= -lcrypto -lssl ${TLS_INT}
5DPADD= ${LIBCRYPTO} ${LIBSSL} ${LIBTLS}
6
7WARNINGS= Yes
8CFLAGS+= -DLIBRESSL_INTERNAL -Wall -Wundef -Werror
9CFLAGS+= -I${.CURDIR}/../../../../lib/libtls
10
11REGRESS_TARGETS= \
12 regress-keypairtest
13
14regress-keypairtest: ${PROG}
15 ./keypairtest \
16 ${.CURDIR}/../../libssl/certs/ca.pem \
17 ${.CURDIR}/../../libssl/certs/server.pem \
18 ${.CURDIR}/../../libssl/certs/server.pem
19
20.include <bsd.regress.mk>
diff --git a/src/regress/lib/libtls/keypair/keypairtest.c b/src/regress/lib/libtls/keypair/keypairtest.c
deleted file mode 100644
index 732464af00..0000000000
--- a/src/regress/lib/libtls/keypair/keypairtest.c
+++ /dev/null
@@ -1,211 +0,0 @@
1/* $OpenBSD: keypairtest.c,v 1.4 2018/04/07 16:42:17 jsing Exp $ */
2/*
3 * Copyright (c) 2018 Joel Sing <jsing@openbsd.org>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#include <sys/stat.h>
19
20#include <err.h>
21#include <fcntl.h>
22#include <stdio.h>
23#include <stdlib.h>
24#include <unistd.h>
25
26#include <openssl/x509.h>
27
28#include <tls.h>
29#include <tls_internal.h>
30
31#define PUBKEY_HASH \
32 "SHA256:858d0f94beb0a08eb4f13871ba57bf0a2e081287d0efbaeb3bbac59dd8f1a8e5"
33
34char *cert_file, *key_file, *ocsp_staple_file;
35
36static void
37load_file(const char *filename, const uint8_t **data, size_t *data_len)
38{
39 struct stat sb;
40 uint8_t *buf;
41 size_t len;
42 ssize_t n;
43 int fd;
44
45 if ((fd = open(filename, O_RDONLY)) == -1)
46 err(1, "failed to open '%s'", filename);
47 if ((fstat(fd, &sb)) == -1)
48 err(1, "failed to stat '%s'", filename);
49 if (sb.st_size < 0)
50 err(1, "file size invalid for '%s'", filename);
51 len = (size_t)sb.st_size;
52 if ((buf = malloc(len)) == NULL)
53 err(1, "out of memory");
54 n = read(fd, buf, len);
55 if (n < 0 || (size_t)n != len)
56 err(1, "failed to read '%s'", filename);
57 close(fd);
58
59 *data = buf;
60 *data_len = len;
61}
62
63static int
64compare_mem(char *label, const uint8_t *data1, size_t data1_len,
65 const uint8_t *data2, size_t data2_len)
66{
67 if (data1_len != data2_len) {
68 fprintf(stderr, "FAIL: %s length mismatch (%zu != %zu)\n",
69 label, data1_len, data2_len);
70 return -1;
71 }
72 if (data1 == data2) {
73 fprintf(stderr, "FAIL: %s comparing same memory (%p == %p)\n",
74 label, data1, data2);
75 return -1;
76 }
77 if (memcmp(data1, data2, data1_len) != 0) {
78 fprintf(stderr, "FAIL: %s data mismatch\n", label);
79 return -1;
80 }
81 return 0;
82}
83
84static int
85do_keypair_tests(void)
86{
87 size_t cert_len, key_len, ocsp_staple_len;
88 const uint8_t *cert, *key, *ocsp_staple;
89 X509 *x509_cert = NULL;
90 struct tls_keypair *kp;
91 struct tls_error err;
92 char *hash = NULL;
93 int failed = 1;
94
95 load_file(cert_file, &cert, &cert_len);
96 load_file(key_file, &key, &key_len);
97 load_file(ocsp_staple_file, &ocsp_staple, &ocsp_staple_len);
98
99 if ((kp = tls_keypair_new()) == NULL) {
100 fprintf(stderr, "FAIL: failed to create keypair\n");
101 goto done;
102 }
103
104 if (tls_keypair_set_cert_file(kp, &err, cert_file) == -1) {
105 fprintf(stderr, "FAIL: failed to load cert file: %s\n",
106 err.msg);
107 goto done;
108 }
109 if (tls_keypair_set_key_file(kp, &err, key_file) == -1) {
110 fprintf(stderr, "FAIL: failed to load key file: %s\n", err.msg);
111 goto done;
112 }
113 if (tls_keypair_set_ocsp_staple_file(kp, &err, ocsp_staple_file) == -1) {
114 fprintf(stderr, "FAIL: failed to load ocsp staple file: %s\n",
115 err.msg);
116 goto done;
117 }
118
119 if (compare_mem("certificate", cert, cert_len, kp->cert_mem,
120 kp->cert_len) == -1)
121 goto done;
122 if (compare_mem("key", key, key_len, kp->key_mem, kp->cert_len) == -1)
123 goto done;
124 if (compare_mem("ocsp staple", ocsp_staple, ocsp_staple_len,
125 kp->ocsp_staple, kp->ocsp_staple_len) == -1)
126 goto done;
127 if (strcmp(kp->pubkey_hash, PUBKEY_HASH) != 0) {
128 fprintf(stderr, "FAIL: got pubkey hash '%s', want '%s'",
129 hash, PUBKEY_HASH);
130 goto done;
131 }
132
133 tls_keypair_clear_key(kp);
134
135 if (kp->key_mem != NULL || kp->key_len != 0) {
136 fprintf(stderr, "FAIL: key not cleared (mem %p, len %zu)",
137 kp->key_mem, kp->key_len);
138 goto done;
139 }
140
141 if (tls_keypair_set_cert_mem(kp, &err, cert, cert_len) == -1) {
142 fprintf(stderr, "FAIL: failed to load cert: %s\n", err.msg);
143 goto done;
144 }
145 if (tls_keypair_set_key_mem(kp, &err, key, key_len) == -1) {
146 fprintf(stderr, "FAIL: failed to load key: %s\n", err.msg);
147 goto done;
148 }
149 if (tls_keypair_set_ocsp_staple_mem(kp, &err, ocsp_staple,
150 ocsp_staple_len) == -1) {
151 fprintf(stderr, "FAIL: failed to load ocsp staple: %s\n", err.msg);
152 goto done;
153 }
154 if (compare_mem("certificate", cert, cert_len, kp->cert_mem,
155 kp->cert_len) == -1)
156 goto done;
157 if (compare_mem("key", key, key_len, kp->key_mem, kp->cert_len) == -1)
158 goto done;
159 if (compare_mem("ocsp staple", ocsp_staple, ocsp_staple_len,
160 kp->ocsp_staple, kp->ocsp_staple_len) == -1)
161 goto done;
162 if (strcmp(kp->pubkey_hash, PUBKEY_HASH) != 0) {
163 fprintf(stderr, "FAIL: got pubkey hash '%s', want '%s'",
164 hash, PUBKEY_HASH);
165 goto done;
166 }
167
168 if (tls_keypair_load_cert(kp, &err, &x509_cert) == -1) {
169 fprintf(stderr, "FAIL: failed to load X509 certificate: %s\n",
170 err.msg);
171 goto done;
172 }
173
174 tls_keypair_clear_key(kp);
175
176 if (kp->key_mem != NULL || kp->key_len != 0) {
177 fprintf(stderr, "FAIL: key not cleared (mem %p, len %zu)",
178 kp->key_mem, kp->key_len);
179 goto done;
180 }
181
182 tls_keypair_free(kp);
183
184 failed = 0;
185
186 done:
187 X509_free(x509_cert);
188 free(hash);
189
190 return (failed);
191}
192
193int
194main(int argc, char **argv)
195{
196 int failure = 0;
197
198 if (argc != 4) {
199 fprintf(stderr, "usage: %s ocspstaplefile certfile keyfile\n",
200 argv[0]);
201 return (1);
202 }
203
204 ocsp_staple_file = argv[1];
205 cert_file = argv[2];
206 key_file = argv[3];
207
208 failure |= do_keypair_tests();
209
210 return (failure);
211}
diff --git a/src/regress/lib/libtls/tls/Makefile b/src/regress/lib/libtls/tls/Makefile
deleted file mode 100644
index 0fbd78481b..0000000000
--- a/src/regress/lib/libtls/tls/Makefile
+++ /dev/null
@@ -1,19 +0,0 @@
1# $OpenBSD: Makefile,v 1.2 2017/05/06 21:56:43 jsing Exp $
2
3PROG= tlstest
4LDADD= -lcrypto -lssl -ltls
5DPADD= ${LIBCRYPTO} ${LIBSSL} ${LIBTLS}
6
7WARNINGS= Yes
8CFLAGS+= -Werror
9
10REGRESS_TARGETS= \
11 regress-tlstest
12
13regress-tlstest: ${PROG}
14 ./tlstest \
15 ${.CURDIR}/../../libssl/certs/ca.pem \
16 ${.CURDIR}/../../libssl/certs/server.pem \
17 ${.CURDIR}/../../libssl/certs/server.pem
18
19.include <bsd.regress.mk>
diff --git a/src/regress/lib/libtls/tls/tlstest.c b/src/regress/lib/libtls/tls/tlstest.c
deleted file mode 100644
index 8a4d5dbb38..0000000000
--- a/src/regress/lib/libtls/tls/tlstest.c
+++ /dev/null
@@ -1,450 +0,0 @@
1/* $OpenBSD: tlstest.c,v 1.10 2018/03/19 16:36:12 jsing Exp $ */
2/*
3 * Copyright (c) 2017 Joel Sing <jsing@openbsd.org>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#include <sys/socket.h>
19
20#include <err.h>
21#include <fcntl.h>
22#include <stdio.h>
23#include <string.h>
24#include <unistd.h>
25
26#include <tls.h>
27
28#define CIRCULAR_BUFFER_SIZE 512
29
30unsigned char client_buffer[CIRCULAR_BUFFER_SIZE];
31unsigned char *client_readptr, *client_writeptr;
32
33unsigned char server_buffer[CIRCULAR_BUFFER_SIZE];
34unsigned char *server_readptr, *server_writeptr;
35
36char *cafile, *certfile, *keyfile;
37
38int debug = 0;
39
40static void
41circular_init(void)
42{
43 client_readptr = client_writeptr = client_buffer;
44 server_readptr = server_writeptr = server_buffer;
45}
46
47static ssize_t
48circular_read(char *name, unsigned char *buf, size_t bufsize,
49 unsigned char **readptr, unsigned char *writeptr,
50 unsigned char *outbuf, size_t outlen)
51{
52 unsigned char *nextptr = *readptr;
53 size_t n = 0;
54
55 while (n < outlen) {
56 if (nextptr == writeptr)
57 break;
58 *outbuf++ = *nextptr++;
59 if ((size_t)(nextptr - buf) >= bufsize)
60 nextptr = buf;
61 *readptr = nextptr;
62 n++;
63 }
64
65 if (debug && n > 0)
66 fprintf(stderr, "%s buffer: read %zi bytes\n", name, n);
67
68 return (n > 0 ? (ssize_t)n : TLS_WANT_POLLIN);
69}
70
71static ssize_t
72circular_write(char *name, unsigned char *buf, size_t bufsize,
73 unsigned char *readptr, unsigned char **writeptr,
74 const unsigned char *inbuf, size_t inlen)
75{
76 unsigned char *nextptr = *writeptr;
77 unsigned char *prevptr;
78 size_t n = 0;
79
80 while (n < inlen) {
81 prevptr = nextptr++;
82 if ((size_t)(nextptr - buf) >= bufsize)
83 nextptr = buf;
84 if (nextptr == readptr)
85 break;
86 *prevptr = *inbuf++;
87 *writeptr = nextptr;
88 n++;
89 }
90
91 if (debug && n > 0)
92 fprintf(stderr, "%s buffer: wrote %zi bytes\n", name, n);
93
94 return (n > 0 ? (ssize_t)n : TLS_WANT_POLLOUT);
95}
96
97static ssize_t
98client_read(struct tls *ctx, void *buf, size_t buflen, void *cb_arg)
99{
100 return circular_read("client", client_buffer, sizeof(client_buffer),
101 &client_readptr, client_writeptr, buf, buflen);
102}
103
104static ssize_t
105client_write(struct tls *ctx, const void *buf, size_t buflen, void *cb_arg)
106{
107 return circular_write("server", server_buffer, sizeof(server_buffer),
108 server_readptr, &server_writeptr, buf, buflen);
109}
110
111static ssize_t
112server_read(struct tls *ctx, void *buf, size_t buflen, void *cb_arg)
113{
114 return circular_read("server", server_buffer, sizeof(server_buffer),
115 &server_readptr, server_writeptr, buf, buflen);
116}
117
118static ssize_t
119server_write(struct tls *ctx, const void *buf, size_t buflen, void *cb_arg)
120{
121 return circular_write("client", client_buffer, sizeof(client_buffer),
122 client_readptr, &client_writeptr, buf, buflen);
123}
124
125static int
126do_tls_handshake(char *name, struct tls *ctx)
127{
128 int rv;
129
130 rv = tls_handshake(ctx);
131 if (rv == 0)
132 return (1);
133 if (rv == TLS_WANT_POLLIN || rv == TLS_WANT_POLLOUT)
134 return (0);
135
136 errx(1, "%s handshake failed: %s", name, tls_error(ctx));
137}
138
139static int
140do_tls_close(char *name, struct tls *ctx)
141{
142 int rv;
143
144 rv = tls_close(ctx);
145 if (rv == 0)
146 return (1);
147 if (rv == TLS_WANT_POLLIN || rv == TLS_WANT_POLLOUT)
148 return (0);
149
150 errx(1, "%s close failed: %s", name, tls_error(ctx));
151}
152
153static int
154do_client_server_handshake(char *desc, struct tls *client,
155 struct tls *server_cctx)
156{
157 int i, client_done, server_done;
158
159 i = client_done = server_done = 0;
160 do {
161 if (client_done == 0)
162 client_done = do_tls_handshake("client", client);
163 if (server_done == 0)
164 server_done = do_tls_handshake("server", server_cctx);
165 } while (i++ < 100 && (client_done == 0 || server_done == 0));
166
167 if (client_done == 0 || server_done == 0) {
168 printf("FAIL: %s TLS handshake did not complete\n", desc);
169 return (1);
170 }
171
172 return (0);
173}
174
175static int
176do_client_server_close(char *desc, struct tls *client, struct tls *server_cctx)
177{
178 int i, client_done, server_done;
179
180 i = client_done = server_done = 0;
181 do {
182 if (client_done == 0)
183 client_done = do_tls_close("client", client);
184 if (server_done == 0)
185 server_done = do_tls_close("server", server_cctx);
186 } while (i++ < 100 && (client_done == 0 || server_done == 0));
187
188 if (client_done == 0 || server_done == 0) {
189 printf("FAIL: %s TLS close did not complete\n", desc);
190 return (1);
191 }
192
193 return (0);
194}
195
196static int
197do_client_server_test(char *desc, struct tls *client, struct tls *server_cctx)
198{
199 if (do_client_server_handshake(desc, client, server_cctx) != 0)
200 return (1);
201
202 printf("INFO: %s TLS handshake completed successfully\n", desc);
203
204 /* XXX - Do some reads and writes... */
205
206 if (do_client_server_close(desc, client, server_cctx) != 0)
207 return (1);
208
209 printf("INFO: %s TLS close completed successfully\n", desc);
210
211 return (0);
212}
213
214static int
215test_tls_cbs(struct tls *client, struct tls *server)
216{
217 struct tls *server_cctx;
218 int failure;
219
220 circular_init();
221
222 if (tls_accept_cbs(server, &server_cctx, server_read, server_write,
223 NULL) == -1)
224 errx(1, "failed to accept: %s", tls_error(server));
225
226 if (tls_connect_cbs(client, client_read, client_write, NULL,
227 "test") == -1)
228 errx(1, "failed to connect: %s", tls_error(client));
229
230 failure = do_client_server_test("callback", client, server_cctx);
231
232 tls_free(server_cctx);
233
234 return (failure);
235}
236
237static int
238test_tls_fds(struct tls *client, struct tls *server)
239{
240 struct tls *server_cctx;
241 int cfds[2], sfds[2];
242 int failure;
243
244 if (pipe2(cfds, O_NONBLOCK) == -1)
245 err(1, "failed to create pipe");
246 if (pipe2(sfds, O_NONBLOCK) == -1)
247 err(1, "failed to create pipe");
248
249 if (tls_accept_fds(server, &server_cctx, sfds[0], cfds[1]) == -1)
250 errx(1, "failed to accept: %s", tls_error(server));
251
252 if (tls_connect_fds(client, cfds[0], sfds[1], "test") == -1)
253 errx(1, "failed to connect: %s", tls_error(client));
254
255 failure = do_client_server_test("file descriptor", client, server_cctx);
256
257 tls_free(server_cctx);
258
259 close(cfds[0]);
260 close(cfds[1]);
261 close(sfds[0]);
262 close(sfds[1]);
263
264 return (failure);
265}
266
267static int
268test_tls_socket(struct tls *client, struct tls *server)
269{
270 struct tls *server_cctx;
271 int failure;
272 int sv[2];
273
274 if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, PF_UNSPEC,
275 sv) == -1)
276 err(1, "failed to create socketpair");
277
278 if (tls_accept_socket(server, &server_cctx, sv[0]) == -1)
279 errx(1, "failed to accept: %s", tls_error(server));
280
281 if (tls_connect_socket(client, sv[1], "test") == -1)
282 errx(1, "failed to connect: %s", tls_error(client));
283
284 failure = do_client_server_test("socket", client, server_cctx);
285
286 tls_free(server_cctx);
287
288 close(sv[0]);
289 close(sv[1]);
290
291 return (failure);
292}
293
294static int
295do_tls_tests(void)
296{
297 struct tls_config *client_cfg, *server_cfg;
298 struct tls *client, *server;
299 int failure = 0;
300
301 if ((client = tls_client()) == NULL)
302 errx(1, "failed to create tls client");
303 if ((client_cfg = tls_config_new()) == NULL)
304 errx(1, "failed to create tls client config");
305 tls_config_insecure_noverifyname(client_cfg);
306 if (tls_config_set_ca_file(client_cfg, cafile) == -1)
307 errx(1, "failed to set ca: %s", tls_config_error(client_cfg));
308
309 if ((server = tls_server()) == NULL)
310 errx(1, "failed to create tls server");
311 if ((server_cfg = tls_config_new()) == NULL)
312 errx(1, "failed to create tls server config");
313 if (tls_config_set_keypair_file(server_cfg, certfile, keyfile) == -1)
314 errx(1, "failed to set keypair: %s",
315 tls_config_error(server_cfg));
316
317 tls_reset(client);
318 if (tls_configure(client, client_cfg) == -1)
319 errx(1, "failed to configure client: %s", tls_error(client));
320 tls_reset(server);
321 if (tls_configure(server, server_cfg) == -1)
322 errx(1, "failed to configure server: %s", tls_error(server));
323
324 failure |= test_tls_cbs(client, server);
325
326 tls_reset(client);
327 if (tls_configure(client, client_cfg) == -1)
328 errx(1, "failed to configure client: %s", tls_error(client));
329 tls_reset(server);
330 if (tls_configure(server, server_cfg) == -1)
331 errx(1, "failed to configure server: %s", tls_error(server));
332
333 failure |= test_tls_fds(client, server);
334
335 tls_reset(client);
336 if (tls_configure(client, client_cfg) == -1)
337 errx(1, "failed to configure client: %s", tls_error(client));
338 tls_reset(server);
339 if (tls_configure(server, server_cfg) == -1)
340 errx(1, "failed to configure server: %s", tls_error(server));
341
342 tls_config_free(client_cfg);
343 tls_config_free(server_cfg);
344
345 failure |= test_tls_socket(client, server);
346
347 tls_free(client);
348 tls_free(server);
349
350 return (failure);
351}
352
353static int
354do_tls_ordering_tests(void)
355{
356 struct tls *client = NULL, *server = NULL, *server_cctx = NULL;
357 struct tls_config *client_cfg, *server_cfg;
358 int failure = 0;
359
360 circular_init();
361
362 if ((client = tls_client()) == NULL)
363 errx(1, "failed to create tls client");
364 if ((client_cfg = tls_config_new()) == NULL)
365 errx(1, "failed to create tls client config");
366 tls_config_insecure_noverifyname(client_cfg);
367 if (tls_config_set_ca_file(client_cfg, cafile) == -1)
368 errx(1, "failed to set ca: %s", tls_config_error(client_cfg));
369
370 if ((server = tls_server()) == NULL)
371 errx(1, "failed to create tls server");
372 if ((server_cfg = tls_config_new()) == NULL)
373 errx(1, "failed to create tls server config");
374 if (tls_config_set_keypair_file(server_cfg, certfile, keyfile) == -1)
375 errx(1, "failed to set keypair: %s",
376 tls_config_error(server_cfg));
377
378 if (tls_configure(client, client_cfg) == -1)
379 errx(1, "failed to configure client: %s", tls_error(client));
380 if (tls_configure(server, server_cfg) == -1)
381 errx(1, "failed to configure server: %s", tls_error(server));
382
383 tls_config_free(client_cfg);
384 tls_config_free(server_cfg);
385
386 if (tls_handshake(client) != -1) {
387 printf("FAIL: TLS handshake succeeded on unconnnected "
388 "client context\n");
389 failure = 1;
390 goto done;
391 }
392
393 if (tls_accept_cbs(server, &server_cctx, server_read, server_write,
394 NULL) == -1)
395 errx(1, "failed to accept: %s", tls_error(server));
396
397 if (tls_connect_cbs(client, client_read, client_write, NULL,
398 "test") == -1)
399 errx(1, "failed to connect: %s", tls_error(client));
400
401 if (do_client_server_handshake("ordering", client, server_cctx) != 0) {
402 failure = 1;
403 goto done;
404 }
405
406 if (tls_handshake(client) != -1) {
407 printf("FAIL: TLS handshake succeeded twice\n");
408 failure = 1;
409 goto done;
410 }
411
412 if (tls_handshake(server_cctx) != -1) {
413 printf("FAIL: TLS handshake succeeded twice\n");
414 failure = 1;
415 goto done;
416 }
417
418 if (do_client_server_close("ordering", client, server_cctx) != 0) {
419 failure = 1;
420 goto done;
421 }
422
423 done:
424 tls_free(client);
425 tls_free(server);
426 tls_free(server_cctx);
427
428 return (failure);
429}
430
431int
432main(int argc, char **argv)
433{
434 int failure = 0;
435
436 if (argc != 4) {
437 fprintf(stderr, "usage: %s cafile certfile keyfile\n",
438 argv[0]);
439 return (1);
440 }
441
442 cafile = argv[1];
443 certfile = argv[2];
444 keyfile = argv[3];
445
446 failure |= do_tls_tests();
447 failure |= do_tls_ordering_tests();
448
449 return (failure);
450}
diff --git a/src/regress/lib/libtls/verify/Makefile b/src/regress/lib/libtls/verify/Makefile
deleted file mode 100644
index f8e445b7fc..0000000000
--- a/src/regress/lib/libtls/verify/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
1# $OpenBSD: Makefile,v 1.3 2017/01/09 12:34:03 jsing Exp $
2
3PROG= verifytest
4LDADD= -lcrypto -lssl ${TLS_INT}
5DPADD= ${LIBCRYPTO} ${LIBSSL} ${LIBTLS}
6
7WARNINGS= Yes
8CFLAGS+= -Werror
9
10.include <bsd.regress.mk>
diff --git a/src/regress/lib/libtls/verify/verifytest.c b/src/regress/lib/libtls/verify/verifytest.c
deleted file mode 100644
index b41b62fcfb..0000000000
--- a/src/regress/lib/libtls/verify/verifytest.c
+++ /dev/null
@@ -1,524 +0,0 @@
1/* $OpenBSD: verifytest.c,v 1.7 2017/04/30 03:53:31 jsing Exp $ */
2/*
3 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#include <err.h>
19#include <stdio.h>
20#include <stdlib.h>
21
22#include <openssl/x509v3.h>
23#include <tls.h>
24
25extern int tls_check_name(struct tls *ctx, X509 *cert, const char *name,
26 int *match);
27
28struct alt_name {
29 const char name[128];
30 int name_len;
31 int name_type;
32};
33
34struct verify_test {
35 const char common_name[128];
36 int common_name_len;
37 struct alt_name alt_name1;
38 struct alt_name alt_name2;
39 struct alt_name alt_name3;
40 const char name[128];
41 int want_return;
42 int want_match;
43};
44
45struct verify_test verify_tests[] = {
46 {
47 /* CN without SANs - matching. */
48 .common_name = "www.openbsd.org",
49 .common_name_len = -1,
50 .name = "www.openbsd.org",
51 .want_return = 0,
52 .want_match = 1,
53 },
54 {
55 /* Zero length name - non-matching. */
56 .common_name = "www.openbsd.org",
57 .common_name_len = -1,
58 .name = "",
59 .want_return = 0,
60 .want_match = 0,
61 },
62 {
63 /* CN wildcard without SANs - matching. */
64 .common_name = "*.openbsd.org",
65 .common_name_len = -1,
66 .name = "www.openbsd.org",
67 .want_return = 0,
68 .want_match = 1,
69 },
70 {
71 /* CN without SANs - non-matching. */
72 .common_name = "www.openbsdfoundation.org",
73 .common_name_len = -1,
74 .name = "www.openbsd.org",
75 .want_return = 0,
76 .want_match = 0,
77 },
78 {
79 /* CN wildcard without SANs - invalid CN wildcard. */
80 .common_name = "w*.openbsd.org",
81 .common_name_len = -1,
82 .name = "www.openbsd.org",
83 .want_return = 0,
84 .want_match = 0,
85 },
86 {
87 /* CN wildcard without SANs - invalid CN wildcard. */
88 .common_name = "www.*.org",
89 .common_name_len = -1,
90 .name = "www.openbsd.org",
91 .want_return = 0,
92 .want_match = 0,
93 },
94 {
95 /* CN wildcard without SANs - invalid CN wildcard. */
96 .common_name = "www.openbsd.*",
97 .common_name_len = -1,
98 .name = "www.openbsd.org",
99 .want_return = 0,
100 .want_match = 0,
101 },
102 {
103 /* CN wildcard without SANs - invalid CN wildcard. */
104 .common_name = "*",
105 .common_name_len = -1,
106 .name = "www.openbsd.org",
107 .want_return = 0,
108 .want_match = 0,
109 },
110 {
111 /* CN wildcard without SANs - invalid CN wildcard. */
112 .common_name = "*.org",
113 .common_name_len = -1,
114 .name = "www.openbsd.org",
115 .want_return = 0,
116 .want_match = 0,
117 },
118 {
119 /* CN wildcard without SANs - invalid CN wildcard. */
120 .common_name = "*.org",
121 .common_name_len = -1,
122 .name = "openbsd.org",
123 .want_return = 0,
124 .want_match = 0,
125 },
126 {
127 /* CN IPv4 without SANs - matching. */
128 .common_name = "1.2.3.4",
129 .common_name_len = -1,
130 .name = "1.2.3.4",
131 .want_return = 0,
132 .want_match = 1,
133 },
134 {
135 /* CN IPv4 wildcard without SANS - invalid IP wildcard. */
136 .common_name = "*.2.3.4",
137 .common_name_len = -1,
138 .name = "1.2.3.4",
139 .want_return = 0,
140 .want_match = 0,
141 },
142 {
143 /* CN IPv6 without SANs - matching. */
144 .common_name = "cafe::beef",
145 .common_name_len = -1,
146 .name = "cafe::beef",
147 .want_return = 0,
148 .want_match = 1,
149 },
150 {
151 /* CN without SANs - error due to embedded NUL in CN. */
152 .common_name = {
153 0x77, 0x77, 0x77, 0x2e, 0x6f, 0x70, 0x65, 0x6e,
154 0x62, 0x73, 0x64, 0x2e, 0x6f, 0x72, 0x67, 0x00,
155 0x6e, 0x61, 0x73, 0x74, 0x79, 0x2e, 0x6f, 0x72,
156 0x67,
157 },
158 .common_name_len = 25,
159 .name = "www.openbsd.org",
160 .want_return = -1,
161 .want_match = 0,
162 },
163 {
164 /* CN wildcard without SANs - invalid non-matching name. */
165 .common_name = "*.openbsd.org",
166 .common_name_len = -1,
167 .name = ".openbsd.org",
168 .want_return = 0,
169 .want_match = 0,
170 },
171 {
172 /* CN with SANs - matching on first SAN. */
173 .common_name = "www.openbsd.org",
174 .common_name_len = -1,
175 .alt_name1 = {
176 .name = "www.openbsd.org",
177 .name_len = -1,
178 .name_type = GEN_DNS,
179 },
180 .alt_name2 = {
181 .name = "ftp.openbsd.org",
182 .name_len = -1,
183 .name_type = GEN_DNS,
184 },
185 .name = "www.openbsd.org",
186 .want_return = 0,
187 .want_match = 1,
188 },
189 {
190 /* SANs only - matching on first SAN. */
191 .common_name_len = 0,
192 .alt_name1 = {
193 .name = "www.openbsd.org",
194 .name_len = -1,
195 .name_type = GEN_DNS,
196 },
197 .alt_name2 = {
198 .name = "ftp.openbsd.org",
199 .name_len = -1,
200 .name_type = GEN_DNS,
201 },
202 .name = "www.openbsd.org",
203 .want_return = 0,
204 .want_match = 1,
205 },
206 {
207 /* SANs only - matching on second SAN. */
208 .common_name_len = 0,
209 .alt_name1 = {
210 .name = "www.openbsd.org",
211 .name_len = -1,
212 .name_type = GEN_DNS,
213 },
214 .alt_name2 = {
215 .name = "ftp.openbsd.org",
216 .name_len = -1,
217 .name_type = GEN_DNS,
218 },
219 .name = "ftp.openbsd.org",
220 .want_return = 0,
221 .want_match = 1,
222 },
223 {
224 /* SANs only - non-matching. */
225 .common_name_len = 0,
226 .alt_name1 = {
227 .name = "www.openbsd.org",
228 .name_len = -1,
229 .name_type = GEN_DNS,
230 },
231 .alt_name2 = {
232 .name = "ftp.openbsd.org",
233 .name_len = -1,
234 .name_type = GEN_DNS,
235 },
236 .name = "mail.openbsd.org",
237 .want_return = 0,
238 .want_match = 0,
239 },
240 {
241 /* CN with SANs - matching on second SAN. */
242 .common_name = "www.openbsd.org",
243 .common_name_len = -1,
244 .alt_name1 = {
245 .name = "www.openbsd.org",
246 .name_len = -1,
247 .name_type = GEN_DNS,
248 },
249 .alt_name2 = {
250 .name = "ftp.openbsd.org",
251 .name_len = -1,
252 .name_type = GEN_DNS,
253 },
254 .name = "ftp.openbsd.org",
255 .want_return = 0,
256 .want_match = 1,
257 },
258 {
259 /* CN with SANs - matching on wildcard second SAN. */
260 .common_name = "www.openbsdfoundation.org",
261 .common_name_len = -1,
262 .alt_name1 = {
263 .name = "www.openbsdfoundation.org",
264 .name_len = -1,
265 .name_type = GEN_DNS,
266 },
267 .alt_name2 = {
268 .name = "*.openbsd.org",
269 .name_len = -1,
270 .name_type = GEN_DNS,
271 },
272 .name = "www.openbsd.org",
273 .want_return = 0,
274 .want_match = 1,
275 },
276 {
277 /* CN with SANs - non-matching invalid wildcard. */
278 .common_name = "www.openbsdfoundation.org",
279 .common_name_len = -1,
280 .alt_name1 = {
281 .name = "www.openbsdfoundation.org",
282 .name_len = -1,
283 .name_type = GEN_DNS,
284 },
285 .alt_name2 = {
286 .name = "*.org",
287 .name_len = -1,
288 .name_type = GEN_DNS,
289 },
290 .name = "www.openbsd.org",
291 .want_return = 0,
292 .want_match = 0,
293 },
294 {
295 /* CN with SANs - non-matching IPv4 due to GEN_DNS SAN. */
296 .common_name = "www.openbsd.org",
297 .common_name_len = -1,
298 .alt_name1 = {
299 .name = "www.openbsd.org",
300 .name_len = -1,
301 .name_type = GEN_DNS,
302 },
303 .alt_name2 = {
304 .name = "1.2.3.4",
305 .name_len = -1,
306 .name_type = GEN_DNS,
307 },
308 .name = "1.2.3.4",
309 .want_return = 0,
310 .want_match = 0,
311 },
312 {
313 /* CN with SANs - matching IPv4 on GEN_IPADD SAN. */
314 .common_name = "www.openbsd.org",
315 .common_name_len = -1,
316 .alt_name1 = {
317 .name = "www.openbsd.org",
318 .name_len = -1,
319 .name_type = GEN_DNS,
320 },
321 .alt_name2 = {
322 .name = {0x01, 0x02, 0x03, 0x04},
323 .name_len = 4,
324 .name_type = GEN_IPADD,
325 },
326 .name = "1.2.3.4",
327 .want_return = 0,
328 .want_match = 1,
329 },
330 {
331 /* CN with SANs - matching IPv6 on GEN_IPADD SAN. */
332 .common_name = "www.openbsd.org",
333 .common_name_len = -1,
334 .alt_name1 = {
335 .name = "www.openbsd.org",
336 .name_len = -1,
337 .name_type = GEN_DNS,
338 },
339 .alt_name2 = {
340 .name = {
341 0xca, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
342 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0xef,
343 },
344 .name_len = 16,
345 .name_type = GEN_IPADD,
346 },
347 .name = "cafe::beef",
348 .want_return = 0,
349 .want_match = 1,
350 },
351 {
352 /* CN with SANs - error due to embedded NUL in GEN_DNS. */
353 .common_name = "www.openbsd.org.nasty.org",
354 .common_name_len = -1,
355 .alt_name1 = {
356 .name = "www.openbsd.org.nasty.org",
357 .name_len = -1,
358 .name_type = GEN_DNS,
359 },
360 .alt_name2 = {
361 .name = {
362 0x77, 0x77, 0x77, 0x2e, 0x6f, 0x70, 0x65, 0x6e,
363 0x62, 0x73, 0x64, 0x2e, 0x6f, 0x72, 0x67, 0x00,
364 0x6e, 0x61, 0x73, 0x74, 0x79, 0x2e, 0x6f, 0x72,
365 0x67,
366 },
367 .name_len = 25,
368 .name_type = GEN_DNS,
369 },
370 .name = "www.openbsd.org",
371 .want_return = -1,
372 .want_match = 0,
373 },
374 {
375 /* CN with SAN - non-matching due to non-matching SAN. */
376 .common_name = "www.openbsd.org",
377 .common_name_len = -1,
378 .alt_name1 = {
379 .name = "ftp.openbsd.org",
380 .name_len = -1,
381 .name_type = GEN_DNS,
382 },
383 .name = "www.openbsd.org",
384 .want_return = 0,
385 .want_match = 0,
386 },
387 {
388 /* CN with SAN - error due to illegal dNSName. */
389 .common_name = "www.openbsd.org",
390 .common_name_len = -1,
391 .alt_name1 = {
392 .name = " ",
393 .name_len = -1,
394 .name_type = GEN_DNS,
395 },
396 .name = "www.openbsd.org",
397 .want_return = -1,
398 .want_match = 0,
399 },
400};
401
402#define N_VERIFY_TESTS \
403 (sizeof(verify_tests) / sizeof(*verify_tests))
404
405static void
406alt_names_add(STACK_OF(GENERAL_NAME) *alt_name_stack, struct alt_name *alt)
407{
408 ASN1_STRING *alt_name_str;
409 GENERAL_NAME *alt_name;
410
411 if ((alt_name = GENERAL_NAME_new()) == NULL)
412 errx(1, "failed to malloc GENERAL_NAME");
413 alt_name->type = alt->name_type;
414
415 if ((alt_name_str = ASN1_STRING_new()) == NULL)
416 errx(1, "failed to malloc alt name");
417 if (ASN1_STRING_set(alt_name_str, alt->name, alt->name_len) == 0)
418 errx(1, "failed to set alt name");
419
420 switch (alt_name->type) {
421 case GEN_DNS:
422 alt_name->d.dNSName = alt_name_str;
423 break;
424 case GEN_IPADD:
425 alt_name->d.iPAddress = alt_name_str;
426 break;
427 default:
428 errx(1, "unknown alt name type (%i)", alt_name->type);
429 }
430
431 if (sk_GENERAL_NAME_push(alt_name_stack, alt_name) == 0)
432 errx(1, "failed to push alt_name");
433}
434
435static void
436cert_add_alt_names(X509 *cert, struct verify_test *vt)
437{
438 STACK_OF(GENERAL_NAME) *alt_name_stack = NULL;
439
440 if (vt->alt_name1.name_type == 0)
441 return;
442
443 if ((alt_name_stack = sk_GENERAL_NAME_new_null()) == NULL)
444 errx(1, "failed to malloc sk_GENERAL_NAME");
445
446 if (vt->alt_name1.name_type != 0)
447 alt_names_add(alt_name_stack, &vt->alt_name1);
448 if (vt->alt_name2.name_type != 0)
449 alt_names_add(alt_name_stack, &vt->alt_name2);
450 if (vt->alt_name3.name_type != 0)
451 alt_names_add(alt_name_stack, &vt->alt_name3);
452
453 if (X509_add1_ext_i2d(cert, NID_subject_alt_name,
454 alt_name_stack, 0, 0) == 0)
455 errx(1, "failed to set subject alt name");
456
457 sk_GENERAL_NAME_pop_free(alt_name_stack, GENERAL_NAME_free);
458}
459
460static int
461do_verify_test(int test_no, struct verify_test *vt)
462{
463 struct tls *tls;
464 X509_NAME *name;
465 X509 *cert;
466 int failed = 1;
467 int match;
468
469 /* Build certificate structure. */
470 if ((cert = X509_new()) == NULL)
471 errx(1, "failed to malloc X509");
472
473 if (vt->common_name_len != 0) {
474 if ((name = X509_NAME_new()) == NULL)
475 errx(1, "failed to malloc X509_NAME");
476 if (X509_NAME_add_entry_by_NID(name, NID_commonName,
477 MBSTRING_ASC, (unsigned char *)vt->common_name,
478 vt->common_name_len, -1, 0) == 0)
479 errx(1, "failed to add name entry");
480 if (X509_set_subject_name(cert, name) == 0)
481 errx(1, "failed to set subject name");
482 X509_NAME_free(name);
483 }
484
485 if ((tls = tls_client()) == NULL)
486 errx(1, "failed to malloc tls_client");
487
488 cert_add_alt_names(cert, vt);
489
490 match = 1;
491
492 if (tls_check_name(tls, cert, vt->name, &match) != vt->want_return) {
493 fprintf(stderr, "FAIL: test %i failed for check name '%s': "
494 "%s\n", test_no, vt->name, tls_error(tls));
495 goto done;
496 }
497 if (match != vt->want_match) {
498 fprintf(stderr, "FAIL: test %i failed to match name '%s'\n",
499 test_no, vt->name);
500 goto done;
501 }
502
503 failed = 0;
504
505 done:
506 X509_free(cert);
507 tls_free(tls);
508
509 return (failed);
510}
511
512int
513main(int argc, char **argv)
514{
515 int failed = 0;
516 size_t i;
517
518 tls_init();
519
520 for (i = 0; i < N_VERIFY_TESTS; i++)
521 failed += do_verify_test(i, &verify_tests[i]);
522
523 return (failed);
524}