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