diff options
author | jsing <> | 2022-01-30 18:44:45 +0000 |
---|---|---|
committer | jsing <> | 2022-01-30 18:44:45 +0000 |
commit | a24e6b334919c85f647d6b7188f92923394678bb (patch) | |
tree | 81f0a4838dd9c09e2da4f14341ed5cebb6412fd1 | |
parent | 90bd8d8a0aaecfe43c384a58aedb9f0ddc7b187d (diff) | |
download | openbsd-a24e6b334919c85f647d6b7188f92923394678bb.tar.gz openbsd-a24e6b334919c85f647d6b7188f92923394678bb.tar.bz2 openbsd-a24e6b334919c85f647d6b7188f92923394678bb.zip |
Add test coverage for tls_signer when used with a TLS server.
In this configuration the tls_signer is provided with the server
certificate and private key, while the TLS server is configured with a
sign callback and is only provided with the certificate.
-rw-r--r-- | src/regress/lib/libtls/signer/signertest.c | 191 |
1 files changed, 189 insertions, 2 deletions
diff --git a/src/regress/lib/libtls/signer/signertest.c b/src/regress/lib/libtls/signer/signertest.c index ce8a0db8f5..34290a12d6 100644 --- a/src/regress/lib/libtls/signer/signertest.c +++ b/src/regress/lib/libtls/signer/signertest.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* $OpenBSD: signertest.c,v 1.1 2022/01/30 18:38:41 jsing Exp $ */ | 1 | /* $OpenBSD: signertest.c,v 1.2 2022/01/30 18:44:45 jsing Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2018, 2022 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2017, 2018, 2022 Joel Sing <jsing@openbsd.org> |
4 | * | 4 | * |
5 | * Permission to use, copy, modify, and distribute this software for any | 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 | 6 | * purpose with or without fee is hereby granted, provided that the above |
@@ -15,6 +15,7 @@ | |||
15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | 15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
16 | */ | 16 | */ |
17 | 17 | ||
18 | #include <sys/socket.h> | ||
18 | #include <sys/stat.h> | 19 | #include <sys/stat.h> |
19 | 20 | ||
20 | #include <err.h> | 21 | #include <err.h> |
@@ -32,6 +33,7 @@ | |||
32 | #include <tls.h> | 33 | #include <tls.h> |
33 | 34 | ||
34 | const char *cert_path; | 35 | const char *cert_path; |
36 | int sign_cb_count; | ||
35 | 37 | ||
36 | static void | 38 | static void |
37 | hexdump(const unsigned char *buf, size_t len) | 39 | hexdump(const unsigned char *buf, size_t len) |
@@ -268,6 +270,190 @@ do_signer_tests(void) | |||
268 | return failed; | 270 | return failed; |
269 | } | 271 | } |
270 | 272 | ||
273 | static int | ||
274 | do_tls_handshake(char *name, struct tls *ctx) | ||
275 | { | ||
276 | int rv; | ||
277 | |||
278 | rv = tls_handshake(ctx); | ||
279 | if (rv == 0) | ||
280 | return (1); | ||
281 | if (rv == TLS_WANT_POLLIN || rv == TLS_WANT_POLLOUT) | ||
282 | return (0); | ||
283 | |||
284 | errx(1, "%s handshake failed: %s", name, tls_error(ctx)); | ||
285 | } | ||
286 | |||
287 | static int | ||
288 | do_client_server_handshake(char *desc, struct tls *client, | ||
289 | struct tls *server_cctx) | ||
290 | { | ||
291 | int i, client_done, server_done; | ||
292 | |||
293 | i = client_done = server_done = 0; | ||
294 | do { | ||
295 | if (client_done == 0) | ||
296 | client_done = do_tls_handshake("client", client); | ||
297 | if (server_done == 0) | ||
298 | server_done = do_tls_handshake("server", server_cctx); | ||
299 | } while (i++ < 100 && (client_done == 0 || server_done == 0)); | ||
300 | |||
301 | if (client_done == 0 || server_done == 0) { | ||
302 | printf("FAIL: %s TLS handshake did not complete\n", desc); | ||
303 | return (1); | ||
304 | } | ||
305 | |||
306 | return (0); | ||
307 | } | ||
308 | |||
309 | static int | ||
310 | test_tls_handshake_socket(struct tls *client, struct tls *server) | ||
311 | { | ||
312 | struct tls *server_cctx; | ||
313 | int failure; | ||
314 | int sv[2]; | ||
315 | |||
316 | if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, PF_UNSPEC, | ||
317 | sv) == -1) | ||
318 | err(1, "failed to create socketpair"); | ||
319 | |||
320 | if (tls_accept_socket(server, &server_cctx, sv[0]) == -1) | ||
321 | errx(1, "failed to accept: %s", tls_error(server)); | ||
322 | |||
323 | if (tls_connect_socket(client, sv[1], "test") == -1) | ||
324 | errx(1, "failed to connect: %s", tls_error(client)); | ||
325 | |||
326 | failure = do_client_server_handshake("socket", client, server_cctx); | ||
327 | |||
328 | tls_free(server_cctx); | ||
329 | |||
330 | close(sv[0]); | ||
331 | close(sv[1]); | ||
332 | |||
333 | return (failure); | ||
334 | } | ||
335 | |||
336 | static int | ||
337 | test_signer_tls_sign(void *cb_arg, const char *hash, const uint8_t *digest, | ||
338 | size_t digest_len, uint8_t *out_signature, size_t *out_signature_len, | ||
339 | int padding) | ||
340 | { | ||
341 | struct tls_signer *signer = cb_arg; | ||
342 | uint8_t *signature = NULL; | ||
343 | size_t signature_len = 0; | ||
344 | |||
345 | sign_cb_count++; | ||
346 | |||
347 | if (tls_signer_sign(signer, hash, digest, digest_len, &signature, | ||
348 | &signature_len, padding) == -1) | ||
349 | return -1; | ||
350 | |||
351 | memcpy(out_signature, signature, signature_len); | ||
352 | *out_signature_len = signature_len; | ||
353 | |||
354 | free(signature); | ||
355 | |||
356 | return 0; | ||
357 | } | ||
358 | |||
359 | static int | ||
360 | test_signer_tls(char *certfile, char *keyfile, char *cafile) | ||
361 | { | ||
362 | struct tls_config *client_cfg, *server_cfg; | ||
363 | struct tls_signer *signer; | ||
364 | struct tls *client, *server; | ||
365 | int failure = 0; | ||
366 | |||
367 | if ((signer = tls_signer_new()) == NULL) | ||
368 | errx(1, "failed to create tls signer"); | ||
369 | if (tls_signer_add_keypair_file(signer, certfile, keyfile)) | ||
370 | errx(1, "failed to add keypair to signer"); | ||
371 | |||
372 | if ((client = tls_client()) == NULL) | ||
373 | errx(1, "failed to create tls client"); | ||
374 | if ((client_cfg = tls_config_new()) == NULL) | ||
375 | errx(1, "failed to create tls client config"); | ||
376 | tls_config_insecure_noverifyname(client_cfg); | ||
377 | if (tls_config_set_ca_file(client_cfg, cafile) == -1) | ||
378 | errx(1, "failed to set ca: %s", tls_config_error(client_cfg)); | ||
379 | |||
380 | if ((server = tls_server()) == NULL) | ||
381 | errx(1, "failed to create tls server"); | ||
382 | if ((server_cfg = tls_config_new()) == NULL) | ||
383 | errx(1, "failed to create tls server config"); | ||
384 | if (tls_config_set_sign_cb(server_cfg, test_signer_tls_sign, | ||
385 | signer) == -1) | ||
386 | errx(1, "failed to set server signer callback: %s", | ||
387 | tls_config_error(server_cfg)); | ||
388 | if (tls_config_set_cert_file(server_cfg, certfile) == -1) | ||
389 | errx(1, "failed to set server certificate: %s", | ||
390 | tls_config_error(server_cfg)); | ||
391 | |||
392 | if (tls_configure(client, client_cfg) == -1) | ||
393 | errx(1, "failed to configure client: %s", tls_error(client)); | ||
394 | if (tls_configure(server, server_cfg) == -1) | ||
395 | errx(1, "failed to configure server: %s", tls_error(server)); | ||
396 | |||
397 | tls_config_free(client_cfg); | ||
398 | tls_config_free(server_cfg); | ||
399 | |||
400 | failure |= test_tls_handshake_socket(client, server); | ||
401 | |||
402 | tls_signer_free(signer); | ||
403 | tls_free(client); | ||
404 | tls_free(server); | ||
405 | |||
406 | return (failure); | ||
407 | } | ||
408 | |||
409 | static int | ||
410 | do_signer_tls_tests(void) | ||
411 | { | ||
412 | char *server_ecdsa_cert = NULL, *server_ecdsa_key = NULL; | ||
413 | char *server_rsa_cert = NULL, *server_rsa_key = NULL; | ||
414 | char *ca_root_ecdsa = NULL, *ca_root_rsa = NULL; | ||
415 | int failure = 0; | ||
416 | |||
417 | if (asprintf(&ca_root_ecdsa, "%s/%s", cert_path, | ||
418 | "ca-root-ecdsa.pem") == -1) | ||
419 | err(1, "ca ecdsa root"); | ||
420 | if (asprintf(&ca_root_rsa, "%s/%s", cert_path, | ||
421 | "ca-root-rsa.pem") == -1) | ||
422 | err(1, "ca rsa root"); | ||
423 | if (asprintf(&server_ecdsa_cert, "%s/%s", cert_path, | ||
424 | "server1-ecdsa-chain.pem") == -1) | ||
425 | err(1, "server ecdsa chain"); | ||
426 | if (asprintf(&server_ecdsa_key, "%s/%s", cert_path, | ||
427 | "server1-ecdsa.pem") == -1) | ||
428 | err(1, "server ecdsa key"); | ||
429 | if (asprintf(&server_rsa_cert, "%s/%s", cert_path, | ||
430 | "server1-rsa-chain.pem") == -1) | ||
431 | err(1, "server rsa chain"); | ||
432 | if (asprintf(&server_rsa_key, "%s/%s", cert_path, | ||
433 | "server1-rsa.pem") == -1) | ||
434 | err(1, "server rsa key"); | ||
435 | |||
436 | failure |= test_signer_tls(server_ecdsa_cert, server_ecdsa_key, | ||
437 | ca_root_ecdsa); | ||
438 | failure |= test_signer_tls(server_rsa_cert, server_rsa_key, | ||
439 | ca_root_rsa); | ||
440 | |||
441 | if (sign_cb_count != 2) { | ||
442 | fprintf(stderr, "FAIL: sign callback was called %d times, " | ||
443 | "want 2\n", sign_cb_count); | ||
444 | failure |= 1; | ||
445 | } | ||
446 | |||
447 | free(ca_root_ecdsa); | ||
448 | free(ca_root_rsa); | ||
449 | free(server_ecdsa_cert); | ||
450 | free(server_ecdsa_key); | ||
451 | free(server_rsa_cert); | ||
452 | free(server_rsa_key); | ||
453 | |||
454 | return (failure); | ||
455 | } | ||
456 | |||
271 | int | 457 | int |
272 | main(int argc, char **argv) | 458 | main(int argc, char **argv) |
273 | { | 459 | { |
@@ -281,6 +467,7 @@ main(int argc, char **argv) | |||
281 | cert_path = argv[1]; | 467 | cert_path = argv[1]; |
282 | 468 | ||
283 | failure |= do_signer_tests(); | 469 | failure |= do_signer_tests(); |
470 | failure |= do_signer_tls_tests(); | ||
284 | 471 | ||
285 | return (failure); | 472 | return (failure); |
286 | } | 473 | } |