diff options
author | tb <> | 2019-01-24 16:32:29 +0000 |
---|---|---|
committer | tb <> | 2019-01-24 16:32:29 +0000 |
commit | b5cdabff97144772f1f01e34938e4ab9e49a34e7 (patch) | |
tree | 8822a5bcd5ac90178ee3602c965a8c8e7017d828 | |
parent | 1259c2a53d65a2833e0c3ea97b175f592a1b6069 (diff) | |
download | openbsd-b5cdabff97144772f1f01e34938e4ab9e49a34e7.tar.gz openbsd-b5cdabff97144772f1f01e34938e4ab9e49a34e7.tar.bz2 openbsd-b5cdabff97144772f1f01e34938e4ab9e49a34e7.zip |
Add code to visualize the state machine. Both the state machine and the
output will have to be tweaked, but this may as well happen in-tree. To
try it, pkg_add graphviz and run 'make handshake.svg' in this directory.
Committing early so Bob's followers can play.
-rw-r--r-- | src/regress/lib/libssl/handshake/Makefile | 19 | ||||
-rw-r--r-- | src/regress/lib/libssl/handshake/handshake_table.c | 65 |
2 files changed, 79 insertions, 5 deletions
diff --git a/src/regress/lib/libssl/handshake/Makefile b/src/regress/lib/libssl/handshake/Makefile index 592e3b3f66..0b4248191a 100644 --- a/src/regress/lib/libssl/handshake/Makefile +++ b/src/regress/lib/libssl/handshake/Makefile | |||
@@ -1,4 +1,4 @@ | |||
1 | # $OpenBSD: Makefile,v 1.3 2019/01/23 08:31:25 tb Exp $ | 1 | # $OpenBSD: Makefile,v 1.4 2019/01/24 16:32:29 tb Exp $ |
2 | 2 | ||
3 | PROGS += handshake_table | 3 | PROGS += handshake_table |
4 | PROGS += valid_handshakes_terminate | 4 | PROGS += valid_handshakes_terminate |
@@ -15,6 +15,23 @@ CFLAGS += -DLIBRESSL_INTERNAL -Wundef -Werror -I$(BSDSRCDIR)/lib/libssl | |||
15 | print: handshake_table | 15 | print: handshake_table |
16 | @./handshake_table -C | 16 | @./handshake_table -C |
17 | 17 | ||
18 | handshake.gv: handshake_table | ||
19 | ./handshake_table -g > $@.tmp | ||
20 | mv $@.tmp $@ | ||
21 | |||
22 | CLEANFILES += handshake.gv | ||
23 | |||
24 | .for _FMT in png svg ps | ||
25 | handshake.${_FMT}: handshake.gv | ||
26 | @if [ ! -x /usr/local/bin/dot ]; then \ | ||
27 | echo "pkg_add graphviz to generate png"; \ | ||
28 | false; \ | ||
29 | fi | ||
30 | dot -T${_FMT} handshake.gv -o $@ | ||
31 | |||
32 | CLEANFILES += handshake.${_FMT} | ||
33 | .endfor | ||
34 | |||
18 | .for p in ${PROGS} | 35 | .for p in ${PROGS} |
19 | run-$p: $p | 36 | run-$p: $p |
20 | @echo '\n======== $@ ========' | 37 | @echo '\n======== $@ ========' |
diff --git a/src/regress/lib/libssl/handshake/handshake_table.c b/src/regress/lib/libssl/handshake/handshake_table.c index fb7dd60bb7..8432586b72 100644 --- a/src/regress/lib/libssl/handshake/handshake_table.c +++ b/src/regress/lib/libssl/handshake/handshake_table.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: handshake_table.c,v 1.5 2019/01/24 03:48:09 tb Exp $ */ | 1 | /* $OpenBSD: handshake_table.c,v 1.6 2019/01/24 16:32:29 tb Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2019 Theo Buehler <tb@openbsd.org> | 3 | * Copyright (c) 2019 Theo Buehler <tb@openbsd.org> |
4 | * | 4 | * |
@@ -129,11 +129,14 @@ static struct child stateinfo[][TLS13_NUM_MESSAGE_TYPES] = { | |||
129 | }, | 129 | }, |
130 | }; | 130 | }; |
131 | 131 | ||
132 | const size_t stateinfo_count = sizeof(stateinfo) / sizeof(stateinfo[0]); | ||
133 | |||
132 | void build_table(enum tls13_message_type | 134 | void build_table(enum tls13_message_type |
133 | table[UINT8_MAX][TLS13_NUM_MESSAGE_TYPES], struct child current, | 135 | table[UINT8_MAX][TLS13_NUM_MESSAGE_TYPES], struct child current, |
134 | struct child end, struct child path[], uint8_t flags, unsigned int depth); | 136 | struct child end, struct child path[], uint8_t flags, unsigned int depth); |
135 | size_t count_handshakes(void); | 137 | size_t count_handshakes(void); |
136 | const char *flag2str(uint8_t flag); | 138 | const char *flag2str(uint8_t flag); |
139 | int generate_graphics(void); | ||
137 | const char *mt2str(enum tls13_message_type mt); | 140 | const char *mt2str(enum tls13_message_type mt); |
138 | void print_entry(enum tls13_message_type path[TLS13_NUM_MESSAGE_TYPES], | 141 | void print_entry(enum tls13_message_type path[TLS13_NUM_MESSAGE_TYPES], |
139 | uint8_t flags); | 142 | uint8_t flags); |
@@ -282,6 +285,51 @@ print_entry(enum tls13_message_type path[TLS13_NUM_MESSAGE_TYPES], | |||
282 | printf("\t},\n"); | 285 | printf("\t},\n"); |
283 | } | 286 | } |
284 | 287 | ||
288 | int | ||
289 | generate_graphics(void) | ||
290 | { | ||
291 | unsigned int start, end; | ||
292 | uint8_t flag; | ||
293 | uint8_t forced, illegal; | ||
294 | |||
295 | printf("digraph G {\n"); | ||
296 | printf("\t%s [shape=box]\n", mt2str(CLIENT_HELLO)); | ||
297 | printf("\t%s [shape=box]\n", mt2str(APPLICATION_DATA)); | ||
298 | |||
299 | for (start = 1; start < stateinfo_count - 1; start++) { | ||
300 | for (end = 0; stateinfo[start][end].mt != 0; end++) { | ||
301 | flag = stateinfo[start][end].flag; | ||
302 | forced = stateinfo[start][end].forced; | ||
303 | illegal = stateinfo[start][end].illegal; | ||
304 | |||
305 | printf("\t%s -> %s", mt2str(start), | ||
306 | mt2str(stateinfo[start][end].mt)); | ||
307 | |||
308 | if (flag || forced || illegal) | ||
309 | printf(" ["); | ||
310 | if (flag) | ||
311 | printf("label=\"%s\"%s", flag2str(flag), | ||
312 | (forced || illegal) ? ", " : ""); | ||
313 | if (forced) { | ||
314 | printf("label=\"if "); | ||
315 | print_flags(stateinfo[start][end].forced); | ||
316 | printf("\"%s", illegal ? ", " : ""); | ||
317 | } | ||
318 | if (illegal) { | ||
319 | printf("label=\"not if "); | ||
320 | print_flags(stateinfo[start][end].illegal); | ||
321 | printf("\""); | ||
322 | } | ||
323 | if (flag || forced || illegal) | ||
324 | printf("]"); | ||
325 | printf(";\n"); | ||
326 | } | ||
327 | } | ||
328 | |||
329 | printf("}\n"); | ||
330 | return 0; | ||
331 | } | ||
332 | |||
285 | extern enum tls13_message_type handshakes[][TLS13_NUM_MESSAGE_TYPES]; | 333 | extern enum tls13_message_type handshakes[][TLS13_NUM_MESSAGE_TYPES]; |
286 | extern size_t handshake_count; | 334 | extern size_t handshake_count; |
287 | 335 | ||
@@ -377,7 +425,7 @@ verify_table(enum tls13_message_type table[UINT8_MAX][TLS13_NUM_MESSAGE_TYPES], | |||
377 | __dead void | 425 | __dead void |
378 | usage(void) | 426 | usage(void) |
379 | { | 427 | { |
380 | fprintf(stderr, "usage: handshake_table [-C]\n"); | 428 | fprintf(stderr, "usage: handshake_table [-C | -g]\n"); |
381 | exit(1); | 429 | exit(1); |
382 | } | 430 | } |
383 | 431 | ||
@@ -400,13 +448,16 @@ main(int argc, char *argv[]) | |||
400 | struct child path[TLS13_NUM_MESSAGE_TYPES] = {{0}}; | 448 | struct child path[TLS13_NUM_MESSAGE_TYPES] = {{0}}; |
401 | uint8_t flags = NEGOTIATED; | 449 | uint8_t flags = NEGOTIATED; |
402 | unsigned int depth = 0; | 450 | unsigned int depth = 0; |
403 | int ch, print = 0; | 451 | int ch, graphviz = 0, print = 0; |
404 | 452 | ||
405 | while ((ch = getopt(argc, argv, "C")) != -1) { | 453 | while ((ch = getopt(argc, argv, "Cg")) != -1) { |
406 | switch (ch) { | 454 | switch (ch) { |
407 | case 'C': | 455 | case 'C': |
408 | print = 1; | 456 | print = 1; |
409 | break; | 457 | break; |
458 | case 'g': | ||
459 | graphviz = 1; | ||
460 | break; | ||
410 | default: | 461 | default: |
411 | usage(); | 462 | usage(); |
412 | } | 463 | } |
@@ -417,6 +468,12 @@ main(int argc, char *argv[]) | |||
417 | if (argc != 0) | 468 | if (argc != 0) |
418 | usage(); | 469 | usage(); |
419 | 470 | ||
471 | if (graphviz && print) | ||
472 | usage(); | ||
473 | |||
474 | if (graphviz) | ||
475 | return generate_graphics(); | ||
476 | |||
420 | build_table(hs_table, start, end, path, flags, depth); | 477 | build_table(hs_table, start, end, path, flags, depth); |
421 | if (!verify_table(hs_table, print)) | 478 | if (!verify_table(hs_table, print)) |
422 | return 1; | 479 | return 1; |