xref: /openbsd-src/regress/lib/libtls/signer/signertest.c (revision 3da24e266c6277c5c9261103034f973c24e71aa3)
1*3da24e26Stb /* $OpenBSD: signertest.c,v 1.6 2023/04/14 12:41:26 tb Exp $ */
2f3b67b24Sjsing /*
393631cf1Sjsing  * Copyright (c) 2017, 2018, 2022 Joel Sing <jsing@openbsd.org>
4f3b67b24Sjsing  *
5f3b67b24Sjsing  * Permission to use, copy, modify, and distribute this software for any
6f3b67b24Sjsing  * purpose with or without fee is hereby granted, provided that the above
7f3b67b24Sjsing  * copyright notice and this permission notice appear in all copies.
8f3b67b24Sjsing  *
9f3b67b24Sjsing  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10f3b67b24Sjsing  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11f3b67b24Sjsing  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12f3b67b24Sjsing  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13f3b67b24Sjsing  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14f3b67b24Sjsing  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15f3b67b24Sjsing  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16f3b67b24Sjsing  */
17f3b67b24Sjsing 
1893631cf1Sjsing #include <sys/socket.h>
19f3b67b24Sjsing #include <sys/stat.h>
20f3b67b24Sjsing 
21f3b67b24Sjsing #include <err.h>
22f3b67b24Sjsing #include <fcntl.h>
23f3b67b24Sjsing #include <stdio.h>
24f3b67b24Sjsing #include <stdlib.h>
25f3b67b24Sjsing #include <string.h>
26f3b67b24Sjsing #include <unistd.h>
27f3b67b24Sjsing 
28f3b67b24Sjsing #include <openssl/bio.h>
29f3b67b24Sjsing #include <openssl/err.h>
30f3b67b24Sjsing #include <openssl/pem.h>
31f3b67b24Sjsing #include <openssl/x509.h>
32f3b67b24Sjsing 
33f3b67b24Sjsing #include <tls.h>
34f3b67b24Sjsing 
350a0c1beeStb #include "tls_internal.h"
360a0c1beeStb 
37*3da24e26Stb #ifndef CERTSDIR
38*3da24e26Stb #define CERTSDIR "."
39*3da24e26Stb #endif
40*3da24e26Stb 
41*3da24e26Stb const char *cert_path = CERTSDIR;
4293631cf1Sjsing int sign_cb_count;
43f3b67b24Sjsing 
44f3b67b24Sjsing static void
hexdump(const unsigned char * buf,size_t len)45f3b67b24Sjsing hexdump(const unsigned char *buf, size_t len)
46f3b67b24Sjsing {
47f3b67b24Sjsing 	size_t i;
48f3b67b24Sjsing 
49f3b67b24Sjsing 	for (i = 1; i <= len; i++)
50f3b67b24Sjsing 		fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "" : "\n");
51f3b67b24Sjsing 
52f3b67b24Sjsing 	fprintf(stderr, "\n");
53f3b67b24Sjsing }
54f3b67b24Sjsing 
55f3b67b24Sjsing static void
load_file(const char * filename,const uint8_t ** data,size_t * data_len)56f3b67b24Sjsing load_file(const char *filename, const uint8_t **data, size_t *data_len)
57f3b67b24Sjsing {
58f3b67b24Sjsing 	char *filepath;
59f3b67b24Sjsing 	struct stat sb;
60f3b67b24Sjsing 	uint8_t *buf;
61f3b67b24Sjsing 	size_t len;
62f3b67b24Sjsing 	ssize_t n;
63f3b67b24Sjsing 	int fd;
64f3b67b24Sjsing 
65f3b67b24Sjsing 	if (asprintf(&filepath, "%s/%s", cert_path, filename) == -1)
66f3b67b24Sjsing 		err(1, "asprintf");
67f3b67b24Sjsing 	if ((fd = open(filepath, O_RDONLY)) == -1)
68f3b67b24Sjsing 		err(1, "failed to open '%s'", filepath);
69f3b67b24Sjsing 	if ((fstat(fd, &sb)) == -1)
70f3b67b24Sjsing 		err(1, "failed to stat '%s'", filepath);
71f3b67b24Sjsing 	if (sb.st_size < 0)
72f3b67b24Sjsing 		err(1, "file size invalid for '%s'", filepath);
73f3b67b24Sjsing 	len = (size_t)sb.st_size;
74f3b67b24Sjsing 	if ((buf = malloc(len)) == NULL)
75f3b67b24Sjsing 		err(1, "out of memory");
76f3b67b24Sjsing 	n = read(fd, buf, len);
77f3b67b24Sjsing 	if (n < 0 || (size_t)n != len)
78f3b67b24Sjsing 		err(1, "failed to read '%s'", filepath);
79f3b67b24Sjsing 	close(fd);
80f3b67b24Sjsing 
81f3b67b24Sjsing 	*data = buf;
82f3b67b24Sjsing 	*data_len = len;
83f3b67b24Sjsing 
84f3b67b24Sjsing 	free(filepath);
85f3b67b24Sjsing }
86f3b67b24Sjsing 
87f3b67b24Sjsing static int
compare_mem(char * label,const uint8_t * data1,size_t data1_len,const uint8_t * data2,size_t data2_len)88f3b67b24Sjsing compare_mem(char *label, const uint8_t *data1, size_t data1_len,
89f3b67b24Sjsing     const uint8_t *data2, size_t data2_len)
90f3b67b24Sjsing {
91f3b67b24Sjsing 	if (data1_len != data2_len) {
92f3b67b24Sjsing 		fprintf(stderr, "FAIL: %s length mismatch (%zu != %zu)\n",
93f3b67b24Sjsing 		    label, data1_len, data2_len);
94f3b67b24Sjsing 		fprintf(stderr, "Got:\n");
95f3b67b24Sjsing 		hexdump(data1, data1_len);
96f3b67b24Sjsing 		fprintf(stderr, "Want:\n");
97f3b67b24Sjsing 		hexdump(data2, data2_len);
98f3b67b24Sjsing 		return -1;
99f3b67b24Sjsing 	}
100f3b67b24Sjsing 	if (data1 == data2) {
101f3b67b24Sjsing 		fprintf(stderr, "FAIL: %s comparing same memory (%p == %p)\n",
102f3b67b24Sjsing 		    label, data1, data2);
103f3b67b24Sjsing 		return -1;
104f3b67b24Sjsing 	}
105f3b67b24Sjsing 	if (memcmp(data1, data2, data1_len) != 0) {
106f3b67b24Sjsing 		fprintf(stderr, "FAIL: %s data mismatch\n", label);
107f3b67b24Sjsing 		fprintf(stderr, "Got:\n");
108f3b67b24Sjsing 		hexdump(data1, data1_len);
109f3b67b24Sjsing 		fprintf(stderr, "Want:\n");
110f3b67b24Sjsing 		hexdump(data2, data2_len);
111f3b67b24Sjsing 		return -1;
112f3b67b24Sjsing 	}
113f3b67b24Sjsing 	return 0;
114f3b67b24Sjsing }
115f3b67b24Sjsing 
116f3b67b24Sjsing const char *server_ecdsa_pubkey_hash = \
117f3b67b24Sjsing     "SHA256:cef2616ece9a57a76d072013b0faad2232511487c67c45bf00fbcecc070e2f5b";
118f3b67b24Sjsing const char *server_rsa_pubkey_hash = \
119f3b67b24Sjsing     "SHA256:f03c535d374614e7356c0a4e6fd37fe94297b60ed86212adcba40e8e0b07bc9f";
120f3b67b24Sjsing const char *server_unknown_pubkey_hash = \
121f3b67b24Sjsing     "SHA256:f03c535d374614e7356c0a4e6fd37fe94297b60ed86212adcba40e8e0b07bc9e";
122f3b67b24Sjsing 
123f3b67b24Sjsing const uint8_t test_digest[] = {
124f3b67b24Sjsing 	0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
125f3b67b24Sjsing 	0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
126f3b67b24Sjsing 	0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
127f3b67b24Sjsing 	0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
128f3b67b24Sjsing };
129f3b67b24Sjsing 
130f3b67b24Sjsing const uint8_t test_rsa_signature[] = {
131f3b67b24Sjsing 	0x77, 0xfb, 0xdd, 0x41, 0x45, 0x40, 0x25, 0xd6,
132f3b67b24Sjsing 	0x01, 0xe0, 0x59, 0x04, 0x65, 0xae, 0xa1, 0x59,
133f3b67b24Sjsing 	0xae, 0xa2, 0x44, 0x08, 0xf7, 0x02, 0x3d, 0xe4,
134f3b67b24Sjsing 	0xc6, 0x0d, 0x4d, 0x9a, 0x3a, 0xce, 0x34, 0xbe,
135f3b67b24Sjsing 	0x2e, 0xc0, 0xfc, 0xbd, 0x5b, 0x21, 0xe4, 0xbb,
136f3b67b24Sjsing 	0xce, 0x02, 0xfd, 0xc3, 0xfc, 0x3d, 0x25, 0xe7,
137f3b67b24Sjsing 	0xd1, 0x9a, 0x13, 0x60, 0xcb, 0x07, 0xda, 0x23,
138f3b67b24Sjsing 	0xf7, 0xa3, 0xf0, 0xaf, 0x16, 0x1b, 0x28, 0x54,
139f3b67b24Sjsing 	0x0a, 0x3c, 0xc1, 0x31, 0x08, 0x0f, 0x2f, 0xce,
140f3b67b24Sjsing 	0x6d, 0x09, 0x45, 0x48, 0xee, 0x37, 0xa8, 0xc3,
141f3b67b24Sjsing 	0x91, 0xcb, 0xde, 0xad, 0xc6, 0xcf, 0x18, 0x19,
142f3b67b24Sjsing 	0xeb, 0xad, 0x08, 0x66, 0x2f, 0xce, 0x1d, 0x07,
143f3b67b24Sjsing 	0xe3, 0x03, 0x84, 0x00, 0xca, 0x0f, 0x1d, 0x0f,
144f3b67b24Sjsing 	0x0e, 0x6e, 0x54, 0xc1, 0x39, 0x3f, 0x2a, 0x78,
145f3b67b24Sjsing 	0xc8, 0xa3, 0x6d, 0x52, 0xb9, 0x26, 0x8e, 0x7e,
146f3b67b24Sjsing 	0x7a, 0x18, 0x3c, 0x8a, 0x50, 0xa3, 0xad, 0xab,
147f3b67b24Sjsing 	0xd0, 0x03, 0xc5, 0x3e, 0xa5, 0x46, 0x87, 0xb0,
148f3b67b24Sjsing 	0x03, 0xde, 0xd9, 0xe5, 0x4d, 0x73, 0x95, 0xcf,
149f3b67b24Sjsing 	0xe1, 0x59, 0x8e, 0x2e, 0x50, 0x69, 0xe6, 0x20,
150f3b67b24Sjsing 	0xaf, 0x21, 0x4f, 0xe6, 0xc4, 0x86, 0x11, 0x36,
151f3b67b24Sjsing 	0x79, 0x68, 0x83, 0xde, 0x0e, 0x81, 0xde, 0x2e,
152f3b67b24Sjsing 	0xd0, 0x19, 0x3f, 0x4b, 0xad, 0x3e, 0xbf, 0xdd,
153f3b67b24Sjsing 	0x14, 0x4d, 0x66, 0xf3, 0x7f, 0x7d, 0xca, 0xed,
154f3b67b24Sjsing 	0x99, 0x62, 0xdc, 0x7c, 0xb2, 0x8b, 0x57, 0xcb,
155f3b67b24Sjsing 	0xdf, 0xed, 0x16, 0x13, 0x86, 0xd8, 0xd8, 0xb4,
156f3b67b24Sjsing 	0x44, 0x6e, 0xd5, 0x54, 0xbc, 0xdf, 0xe7, 0x34,
157f3b67b24Sjsing 	0x10, 0xa4, 0x17, 0x5f, 0xb7, 0xe1, 0x33, 0x2c,
158f3b67b24Sjsing 	0xc1, 0x70, 0x5b, 0x87, 0x0d, 0x39, 0xee, 0xe8,
159f3b67b24Sjsing 	0xec, 0x18, 0x92, 0xe8, 0x95, 0xa8, 0x93, 0x26,
160f3b67b24Sjsing 	0xdf, 0x26, 0x93, 0x96, 0xfd, 0xad, 0x81, 0xb6,
161f3b67b24Sjsing 	0xeb, 0x72, 0x9c, 0xd4, 0xcc, 0xf6, 0x9f, 0xb0,
162f3b67b24Sjsing 	0xbb, 0xbd, 0xbd, 0x44, 0x1c, 0x99, 0x07, 0x6d,
163f3b67b24Sjsing };
164f3b67b24Sjsing 
165f3b67b24Sjsing static int
do_signer_tests(void)166f3b67b24Sjsing do_signer_tests(void)
167f3b67b24Sjsing {
168f3b67b24Sjsing 	char *server_rsa_filepath = NULL;
169f3b67b24Sjsing 	const uint8_t *server_ecdsa = NULL;
170f3b67b24Sjsing 	size_t server_ecdsa_len;
171f3b67b24Sjsing 	struct tls_signer *signer = NULL;
172f3b67b24Sjsing 	uint8_t *signature = NULL;
173f3b67b24Sjsing 	size_t signature_len;
174f3b67b24Sjsing 	EC_KEY *ec_key = NULL;
175f3b67b24Sjsing 	X509 *x509 = NULL;
176f3b67b24Sjsing 	BIO *bio = NULL;
177f3b67b24Sjsing 	int failed = 1;
178f3b67b24Sjsing 
179f3b67b24Sjsing 	load_file("server1-ecdsa.pem", &server_ecdsa, &server_ecdsa_len);
180f3b67b24Sjsing 
181f3b67b24Sjsing 	if (asprintf(&server_rsa_filepath, "%s/%s", cert_path,
182f3b67b24Sjsing 	    "server1-rsa.pem") == -1) {
183f3b67b24Sjsing 		fprintf(stderr, "FAIL: failed to build rsa file path\n");
184f3b67b24Sjsing 		goto failure;
185f3b67b24Sjsing 	}
186f3b67b24Sjsing 
187f3b67b24Sjsing 	/* Load the ECDSA public key - we'll need it later. */
188f3b67b24Sjsing 	if ((bio = BIO_new_mem_buf(server_ecdsa, server_ecdsa_len)) == NULL) {
189f3b67b24Sjsing 		fprintf(stderr, "FAIL: failed to create bio\n");
190f3b67b24Sjsing 		goto failure;
191f3b67b24Sjsing 	}
192f3b67b24Sjsing 	if ((x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL)) == NULL) {
193f3b67b24Sjsing 		fprintf(stderr, "FAIL: failed to load certificate\n");
194f3b67b24Sjsing 		goto failure;
195f3b67b24Sjsing 	}
196f3b67b24Sjsing 	if ((ec_key = EVP_PKEY_get1_EC_KEY(X509_get0_pubkey(x509))) == NULL) {
197f3b67b24Sjsing 		fprintf(stderr, "FAIL: failed to get EC public key\n");
198f3b67b24Sjsing 		goto failure;
199f3b67b24Sjsing 	}
200f3b67b24Sjsing 
201f3b67b24Sjsing 	/* Create signer and add key pairs (one ECDSA, one RSA). */
202f3b67b24Sjsing 	if ((signer = tls_signer_new()) == NULL) {
203f3b67b24Sjsing 		fprintf(stderr, "FAIL: failed to create tls signer\n");
204f3b67b24Sjsing 		goto failure;
205f3b67b24Sjsing 	}
206f3b67b24Sjsing 	if (tls_signer_add_keypair_mem(signer, server_ecdsa, server_ecdsa_len,
207f3b67b24Sjsing 	    server_ecdsa, server_ecdsa_len) == -1) {
208f3b67b24Sjsing 		fprintf(stderr, "FAIL: failed to add ECDSA keypair to tls "
209f3b67b24Sjsing 		    "signer: %s\n", tls_signer_error(signer));
210f3b67b24Sjsing 		goto failure;
211f3b67b24Sjsing 	}
212f3b67b24Sjsing 	if (tls_signer_add_keypair_file(signer, server_rsa_filepath,
213f3b67b24Sjsing 	    server_rsa_filepath) == -1) {
214f3b67b24Sjsing 		fprintf(stderr, "FAIL: failed to add RSA keypair to tls "
215f3b67b24Sjsing 		    "signer: %s\n", tls_signer_error(signer));
216f3b67b24Sjsing 		goto failure;
217f3b67b24Sjsing 	}
218f3b67b24Sjsing 
219f3b67b24Sjsing 	/* Sign with RSA. */
220f3b67b24Sjsing 	if (tls_signer_sign(signer, server_rsa_pubkey_hash, test_digest,
22131570ee1Sjsing 	    sizeof(test_digest), TLS_PADDING_RSA_PKCS1, &signature,
222b4ea5c75Sjsing 	    &signature_len) == -1) {
223f3b67b24Sjsing 		fprintf(stderr, "FAIL: failed to sign with RSA key: %s\n",
224f3b67b24Sjsing 		    tls_signer_error(signer));
225f3b67b24Sjsing 		goto failure;
226f3b67b24Sjsing 	}
227f3b67b24Sjsing 	if (compare_mem("rsa signature", signature, signature_len,
228f3b67b24Sjsing 	    test_rsa_signature, sizeof(test_rsa_signature)) == -1)
229f3b67b24Sjsing 		goto failure;
230f3b67b24Sjsing 
231f3b67b24Sjsing 	free(signature);
232f3b67b24Sjsing 	signature = NULL;
233f3b67b24Sjsing 
234f3b67b24Sjsing 	/*
235f3b67b24Sjsing 	 * Sign with ECDSA - ECDSA signatures are non-deterministic so we cannot
236f3b67b24Sjsing 	 * check against a known value, rather we can only verify the signature.
237f3b67b24Sjsing 	 */
238f3b67b24Sjsing 	if (tls_signer_sign(signer, server_ecdsa_pubkey_hash, test_digest,
23931570ee1Sjsing 	    sizeof(test_digest), TLS_PADDING_NONE, &signature,
24031570ee1Sjsing 	    &signature_len) == -1) {
241f3b67b24Sjsing 		fprintf(stderr, "FAIL: failed to sign with ECDSA key: %s\n",
242f3b67b24Sjsing 		    tls_signer_error(signer));
243f3b67b24Sjsing 		goto failure;
244f3b67b24Sjsing 	}
245f3b67b24Sjsing 	if (ECDSA_verify(0, test_digest, sizeof(test_digest), signature,
246f3b67b24Sjsing 	    signature_len, ec_key) != 1) {
247f3b67b24Sjsing 		fprintf(stderr, "FAIL: failed to verify ECDSA signature\n");
248f3b67b24Sjsing 		goto failure;
249f3b67b24Sjsing 	}
250f3b67b24Sjsing 
251f3b67b24Sjsing 	free(signature);
252f3b67b24Sjsing 	signature = NULL;
253f3b67b24Sjsing 
254f3b67b24Sjsing 	/* Attempt to sign with an unknown cert pubkey hash. */
255f3b67b24Sjsing 	if (tls_signer_sign(signer, server_unknown_pubkey_hash, test_digest,
25631570ee1Sjsing 	    sizeof(test_digest), TLS_PADDING_NONE, &signature,
25731570ee1Sjsing 	    &signature_len) != -1) {
258f3b67b24Sjsing 		fprintf(stderr, "FAIL: signing succeeded with unknown key\n");
259f3b67b24Sjsing 		goto failure;
260f3b67b24Sjsing 	}
261f3b67b24Sjsing 	if (strcmp(tls_signer_error(signer), "key not found") != 0) {
262f3b67b24Sjsing 		fprintf(stderr, "FAIL: got tls signer error '%s', want "
263f3b67b24Sjsing 		    "'key not found'\n", tls_signer_error(signer));
264f3b67b24Sjsing 		goto failure;
265f3b67b24Sjsing 	}
266f3b67b24Sjsing 
267f3b67b24Sjsing 	failed = 0;
268f3b67b24Sjsing 
269f3b67b24Sjsing  failure:
270f3b67b24Sjsing 	BIO_free(bio);
271f3b67b24Sjsing 	EC_KEY_free(ec_key);
272f3b67b24Sjsing 	X509_free(x509);
273f3b67b24Sjsing 	tls_signer_free(signer);
274f3b67b24Sjsing 	free((uint8_t *)server_ecdsa);
275f3b67b24Sjsing 	free(server_rsa_filepath);
276f3b67b24Sjsing 	free(signature);
277f3b67b24Sjsing 
278f3b67b24Sjsing 	return failed;
279f3b67b24Sjsing }
280f3b67b24Sjsing 
28193631cf1Sjsing static int
do_tls_handshake(char * name,struct tls * ctx)28293631cf1Sjsing do_tls_handshake(char *name, struct tls *ctx)
28393631cf1Sjsing {
28493631cf1Sjsing 	int rv;
28593631cf1Sjsing 
28693631cf1Sjsing 	rv = tls_handshake(ctx);
28793631cf1Sjsing 	if (rv == 0)
28893631cf1Sjsing 		return (1);
28993631cf1Sjsing 	if (rv == TLS_WANT_POLLIN || rv == TLS_WANT_POLLOUT)
29093631cf1Sjsing 		return (0);
29193631cf1Sjsing 
29293631cf1Sjsing 	errx(1, "%s handshake failed: %s", name, tls_error(ctx));
29393631cf1Sjsing }
29493631cf1Sjsing 
29593631cf1Sjsing static int
do_client_server_handshake(char * desc,struct tls * client,struct tls * server_cctx)29693631cf1Sjsing do_client_server_handshake(char *desc, struct tls *client,
29793631cf1Sjsing     struct tls *server_cctx)
29893631cf1Sjsing {
29993631cf1Sjsing 	int i, client_done, server_done;
30093631cf1Sjsing 
30193631cf1Sjsing 	i = client_done = server_done = 0;
30293631cf1Sjsing 	do {
30393631cf1Sjsing 		if (client_done == 0)
30493631cf1Sjsing 			client_done = do_tls_handshake("client", client);
30593631cf1Sjsing 		if (server_done == 0)
30693631cf1Sjsing 			server_done = do_tls_handshake("server", server_cctx);
30793631cf1Sjsing 	} while (i++ < 100 && (client_done == 0 || server_done == 0));
30893631cf1Sjsing 
30993631cf1Sjsing 	if (client_done == 0 || server_done == 0) {
31093631cf1Sjsing 		printf("FAIL: %s TLS handshake did not complete\n", desc);
31193631cf1Sjsing 		return (1);
31293631cf1Sjsing 	}
31393631cf1Sjsing 
31493631cf1Sjsing 	return (0);
31593631cf1Sjsing }
31693631cf1Sjsing 
31793631cf1Sjsing static int
test_tls_handshake_socket(struct tls * client,struct tls * server)31893631cf1Sjsing test_tls_handshake_socket(struct tls *client, struct tls *server)
31993631cf1Sjsing {
32093631cf1Sjsing 	struct tls *server_cctx;
32193631cf1Sjsing 	int failure;
32293631cf1Sjsing 	int sv[2];
32393631cf1Sjsing 
32493631cf1Sjsing 	if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, PF_UNSPEC,
32593631cf1Sjsing 	    sv) == -1)
32693631cf1Sjsing 		err(1, "failed to create socketpair");
32793631cf1Sjsing 
32893631cf1Sjsing 	if (tls_accept_socket(server, &server_cctx, sv[0]) == -1)
32993631cf1Sjsing 		errx(1, "failed to accept: %s", tls_error(server));
33093631cf1Sjsing 
33193631cf1Sjsing 	if (tls_connect_socket(client, sv[1], "test") == -1)
33293631cf1Sjsing 		errx(1, "failed to connect: %s", tls_error(client));
33393631cf1Sjsing 
33493631cf1Sjsing 	failure = do_client_server_handshake("socket", client, server_cctx);
33593631cf1Sjsing 
33693631cf1Sjsing 	tls_free(server_cctx);
33793631cf1Sjsing 
33893631cf1Sjsing 	close(sv[0]);
33993631cf1Sjsing 	close(sv[1]);
34093631cf1Sjsing 
34193631cf1Sjsing 	return (failure);
34293631cf1Sjsing }
34393631cf1Sjsing 
34493631cf1Sjsing static int
test_signer_tls_sign(void * cb_arg,const char * pubkey_hash,const uint8_t * input,size_t input_len,int padding_type,uint8_t ** out_signature,size_t * out_signature_len)345b4ea5c75Sjsing test_signer_tls_sign(void *cb_arg, const char *pubkey_hash,
346b4ea5c75Sjsing     const uint8_t *input, size_t input_len, int padding_type,
347b4ea5c75Sjsing     uint8_t **out_signature, size_t *out_signature_len)
34893631cf1Sjsing {
34993631cf1Sjsing 	struct tls_signer *signer = cb_arg;
35093631cf1Sjsing 
35193631cf1Sjsing 	sign_cb_count++;
35293631cf1Sjsing 
353b4ea5c75Sjsing 	return tls_signer_sign(signer, pubkey_hash, input, input_len,
354b4ea5c75Sjsing 	    padding_type, out_signature, out_signature_len);
35593631cf1Sjsing }
35693631cf1Sjsing 
35793631cf1Sjsing static int
test_signer_tls(char * certfile,char * keyfile,char * cafile)35893631cf1Sjsing test_signer_tls(char *certfile, char *keyfile, char *cafile)
35993631cf1Sjsing {
36093631cf1Sjsing 	struct tls_config *client_cfg, *server_cfg;
36193631cf1Sjsing 	struct tls_signer *signer;
36293631cf1Sjsing 	struct tls *client, *server;
36393631cf1Sjsing 	int failure = 0;
36493631cf1Sjsing 
36593631cf1Sjsing 	if ((signer = tls_signer_new()) == NULL)
36693631cf1Sjsing 		errx(1, "failed to create tls signer");
36793631cf1Sjsing 	if (tls_signer_add_keypair_file(signer, certfile, keyfile))
36893631cf1Sjsing 		errx(1, "failed to add keypair to signer");
36993631cf1Sjsing 
37093631cf1Sjsing 	if ((client = tls_client()) == NULL)
37193631cf1Sjsing 		errx(1, "failed to create tls client");
37293631cf1Sjsing 	if ((client_cfg = tls_config_new()) == NULL)
37393631cf1Sjsing 		errx(1, "failed to create tls client config");
37493631cf1Sjsing 	tls_config_insecure_noverifyname(client_cfg);
37593631cf1Sjsing 	if (tls_config_set_ca_file(client_cfg, cafile) == -1)
37693631cf1Sjsing 		errx(1, "failed to set ca: %s", tls_config_error(client_cfg));
37793631cf1Sjsing 
37893631cf1Sjsing 	if ((server = tls_server()) == NULL)
37993631cf1Sjsing 		errx(1, "failed to create tls server");
38093631cf1Sjsing 	if ((server_cfg = tls_config_new()) == NULL)
38193631cf1Sjsing 		errx(1, "failed to create tls server config");
38293631cf1Sjsing 	if (tls_config_set_sign_cb(server_cfg, test_signer_tls_sign,
38393631cf1Sjsing 	    signer) == -1)
38493631cf1Sjsing 		errx(1, "failed to set server signer callback: %s",
38593631cf1Sjsing 		    tls_config_error(server_cfg));
38693631cf1Sjsing 	if (tls_config_set_cert_file(server_cfg, certfile) == -1)
38793631cf1Sjsing 		errx(1, "failed to set server certificate: %s",
38893631cf1Sjsing 		    tls_config_error(server_cfg));
38993631cf1Sjsing 
39093631cf1Sjsing 	if (tls_configure(client, client_cfg) == -1)
39193631cf1Sjsing 		errx(1, "failed to configure client: %s", tls_error(client));
39293631cf1Sjsing 	if (tls_configure(server, server_cfg) == -1)
39393631cf1Sjsing 		errx(1, "failed to configure server: %s", tls_error(server));
39493631cf1Sjsing 
39593631cf1Sjsing 	tls_config_free(client_cfg);
39693631cf1Sjsing 	tls_config_free(server_cfg);
39793631cf1Sjsing 
39893631cf1Sjsing 	failure |= test_tls_handshake_socket(client, server);
39993631cf1Sjsing 
40093631cf1Sjsing 	tls_signer_free(signer);
40193631cf1Sjsing 	tls_free(client);
40293631cf1Sjsing 	tls_free(server);
40393631cf1Sjsing 
40493631cf1Sjsing 	return (failure);
40593631cf1Sjsing }
40693631cf1Sjsing 
40793631cf1Sjsing static int
do_signer_tls_tests(void)40893631cf1Sjsing do_signer_tls_tests(void)
40993631cf1Sjsing {
41093631cf1Sjsing 	char *server_ecdsa_cert = NULL, *server_ecdsa_key = NULL;
41193631cf1Sjsing 	char *server_rsa_cert = NULL, *server_rsa_key = NULL;
41293631cf1Sjsing 	char *ca_root_ecdsa = NULL, *ca_root_rsa = NULL;
41393631cf1Sjsing 	int failure = 0;
41493631cf1Sjsing 
41593631cf1Sjsing 	if (asprintf(&ca_root_ecdsa, "%s/%s", cert_path,
41693631cf1Sjsing 	    "ca-root-ecdsa.pem") == -1)
41793631cf1Sjsing 		err(1, "ca ecdsa root");
41893631cf1Sjsing 	if (asprintf(&ca_root_rsa, "%s/%s", cert_path,
41993631cf1Sjsing 	    "ca-root-rsa.pem") == -1)
42093631cf1Sjsing 		err(1, "ca rsa root");
42193631cf1Sjsing 	if (asprintf(&server_ecdsa_cert, "%s/%s", cert_path,
42293631cf1Sjsing 	    "server1-ecdsa-chain.pem") == -1)
42393631cf1Sjsing 		err(1, "server ecdsa chain");
42493631cf1Sjsing 	if (asprintf(&server_ecdsa_key, "%s/%s", cert_path,
42593631cf1Sjsing 	    "server1-ecdsa.pem") == -1)
42693631cf1Sjsing 		err(1, "server ecdsa key");
42793631cf1Sjsing 	if (asprintf(&server_rsa_cert, "%s/%s", cert_path,
42893631cf1Sjsing 	    "server1-rsa-chain.pem") == -1)
42993631cf1Sjsing 		err(1, "server rsa chain");
43093631cf1Sjsing 	if (asprintf(&server_rsa_key, "%s/%s", cert_path,
43193631cf1Sjsing 	    "server1-rsa.pem") == -1)
43293631cf1Sjsing 		err(1, "server rsa key");
43393631cf1Sjsing 
43493631cf1Sjsing 	failure |= test_signer_tls(server_ecdsa_cert, server_ecdsa_key,
43593631cf1Sjsing 	    ca_root_ecdsa);
43693631cf1Sjsing 	failure |= test_signer_tls(server_rsa_cert, server_rsa_key,
43793631cf1Sjsing 	    ca_root_rsa);
43893631cf1Sjsing 
43993631cf1Sjsing 	if (sign_cb_count != 2) {
44093631cf1Sjsing 		fprintf(stderr, "FAIL: sign callback was called %d times, "
44193631cf1Sjsing 		    "want 2\n", sign_cb_count);
44293631cf1Sjsing 		failure |= 1;
44393631cf1Sjsing 	}
44493631cf1Sjsing 
44593631cf1Sjsing 	free(ca_root_ecdsa);
44693631cf1Sjsing 	free(ca_root_rsa);
44793631cf1Sjsing 	free(server_ecdsa_cert);
44893631cf1Sjsing 	free(server_ecdsa_key);
44993631cf1Sjsing 	free(server_rsa_cert);
45093631cf1Sjsing 	free(server_rsa_key);
45193631cf1Sjsing 
45293631cf1Sjsing 	return (failure);
45393631cf1Sjsing }
45493631cf1Sjsing 
455f3b67b24Sjsing int
main(int argc,char ** argv)456f3b67b24Sjsing main(int argc, char **argv)
457f3b67b24Sjsing {
458f3b67b24Sjsing 	int failure = 0;
459f3b67b24Sjsing 
460*3da24e26Stb 	if (argc > 2) {
461*3da24e26Stb 		fprintf(stderr, "usage: %s [certpath]\n", argv[0]);
462f3b67b24Sjsing 		return (1);
463f3b67b24Sjsing 	}
464*3da24e26Stb 	if (argc == 2)
465f3b67b24Sjsing 		cert_path = argv[1];
466f3b67b24Sjsing 
467f3b67b24Sjsing 	failure |= do_signer_tests();
46893631cf1Sjsing 	failure |= do_signer_tls_tests();
469f3b67b24Sjsing 
470f3b67b24Sjsing 	return (failure);
471f3b67b24Sjsing }
472