1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
#include <stdint.h>
#include "byte.h"
#include "substdio.h"
#include "subfd.h"
#include "subgetopt.h"
#include "stralloc.h"
#include "dns.h"
#include "dnsdoe.h"
#include "exit.h"
stralloc sa = {0};
stralloc out = {0};
static void die_nomem()
{
substdio_putsflush(subfderr, "out of memory\n");
_exit(111);
}
#include <stdio.h>
void main(int argc, char **argv)
{
char *port = "25";
char proto[7] = "._tcp.";
char *host = NULL;
int opt;
int verbose = 0;
while ((opt = sgopt(argc, argv, "vutp:")) != sgoptdone)
{
switch(opt)
{
case 'p': port = sgoptarg; break;
case 't': break;
case 'u': byte_copy(proto, 6, "._udp."); break;
case 'v': verbose = 1;
}
}
argv += sgoptind;
argc -= sgoptind;
if (!argv[0])
{
substdio_putsflush(subfderr, "dnstlsa [-v] [-p port] [-u(dp)|-t(cp)] host (tcp on port 25 is default)\n");
_exit(100);
}
host = argv[0];
if (!stralloc_copyb(&sa, "_", 1)) die_nomem;
if (!stralloc_cats(&sa, port)) die_nomem;
if (!stralloc_cats(&sa, proto)) die_nomem;
if (!stralloc_cats(&sa, host)) die_nomem;
if (verbose)
{
substdio_puts(subfdout, "checking for TLSA records: ");
substdio_put(subfdout, sa.s, sa.len);
substdio_putsflush(subfdout, "\n");
}
dns_init(0);
dnsdoe(dns_tlsa(&out, &sa));
int pos = 0;
unsigned char *response = (unsigned char *)out.s;
while(pos < out.len && out.len - pos > 2 + 4) // sizeof(rrlen) + min(rrdata)
{
unsigned short rrlen = (response[pos] << 8) + response[pos + 1];
pos += 2;
uint8_t usage = response[pos];
uint8_t sel = response[pos + 1];
uint8_t type = response[pos + 2];
if (usage == 0) substdio_puts(subfdout, "usage=0 ");
if (usage == 1) substdio_puts(subfdout, "usage=1 ");
if (usage == 2) substdio_puts(subfdout, "usage=2 ");
if (usage == 3) substdio_puts(subfdout, "usage=3 ");
if (sel == 0) substdio_puts(subfdout, "selector=0 ");
if (sel == 1) substdio_puts(subfdout, "selector=1 ");
if (type == 0) substdio_puts(subfdout, "type=0 "); // full cert
if (type == 1) substdio_puts(subfdout, "type=1 "); // sha256
if (type == 2) substdio_puts(subfdout, "type=2 "); // sha512
substdio_puts(subfdout, "data=");
for (int j = 3; j < rrlen; j++)
{
unsigned char ch = response[pos + j];
substdio_put(subfdout, "0123456789abcdef" + (ch >> 4), 1);
substdio_put(subfdout, "0123456789abcdef" + (ch & 0x0F), 1);
}
substdio_putsflush(subfdout, "\n");
pos += rrlen;
}
_exit(0);
}
|