-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathxe-sni.h
142 lines (120 loc) · 2.77 KB
/
xe-sni.h
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#ifndef xe_sni_h_included
#define xe_sni_h_included
#define PREFIX "\t\t\t\t"
struct tls_rec
{
uint8_t type;
uint16_t version;
uint16_t len;
} __attribute__((packed));
struct tls_hello
{
uint8_t type;
uint8_t len[3];
uint16_t version;
uint8_t random[32];
uint8_t session_id_len;
} __attribute__((packed));
struct tls_ext
{
uint16_t type;
uint16_t len;
} __attribute__((packed));
struct tls_sni
{
uint16_t list_len;
uint8_t type;
uint16_t name_len;
uint8_t name[1];
} __attribute__((packed));
static int
xe_sni(uint8_t *p, uint8_t *end, char *domain)
{
uint16_t *cipher_suites_len;
uint8_t *compress_methods_len;
uint16_t *ext_len;
struct tls_hello *hello;
struct tls_rec *rec = (struct tls_rec *)p;
if (rec->type != 0x16) {
return 0;
}
if ((rec->version != htobe16(0x0301))
&& (rec->version != htobe16(0x0303))) {
return 0;
}
LOG(PREFIX"Probably TLS Handshake (ver 0x%04x)", be16toh(rec->version));
p += sizeof(struct tls_rec);
if (p >= end) {
LOG(PREFIX"TLS Packet too short");
return 0;
}
hello = (struct tls_hello *)p;
if (hello->type != 1) {
LOG(PREFIX"TLS Packet type is not Client Hello");
return 0;
}
LOG(PREFIX"TLS Client Hello");
p += sizeof(struct tls_hello) + hello->session_id_len;
if (p >= end) {
LOG(PREFIX"TLS Packet too short");
return 0;
}
cipher_suites_len = (uint16_t *)p;
p += sizeof(uint16_t) + be16toh(*cipher_suites_len);
if (p >= end) {
LOG(PREFIX"TLS Packet too short");
return 0;
}
compress_methods_len = (uint8_t *)p;
p += sizeof(uint8_t) + *compress_methods_len;
if (p >= end) {
LOG(PREFIX"TLS Packet too short");
return 0;
}
ext_len = (uint16_t *)p;
if (*ext_len == 0) {
LOG(PREFIX"TLS Client Hello has no extensions");
return 0;
}
p += sizeof(uint16_t); /* skip ext len */
for (;;) {
if ((p + sizeof(struct tls_ext)) >= end) {
LOG(PREFIX"TLS Packet too short");
return 0;
}
struct tls_ext *e = (struct tls_ext *)p;
LOG(PREFIX"TLS ext type: %04x, len: %d ", e->type, be16toh(e->len));
if (e->type == 0x0000) {
char server_name[256];
/* sni */
p += sizeof(struct tls_ext);
if ((p + sizeof(struct tls_sni)) >= end) {
LOG(PREFIX"TLS Packet too short");
return 0;
}
struct tls_sni *sni = (struct tls_sni *)p;
if (sni->type == 0x00) {
uint16_t name_len = be16toh(sni->name_len);
if ((p + sizeof(struct tls_sni) + name_len - 1) >= end) {
LOG(PREFIX"TLS Packet too short");
return 0;
}
memcpy(server_name, sni->name, name_len);
server_name[name_len] = '\0';
LOG(PREFIX"TLS SNI: %s", server_name);
if (domain) {
strcpy(domain, server_name);
}
}
break;
}
p += sizeof(struct tls_ext) + be16toh(e->len);
if (p >= end) {
LOG(PREFIX"No TLS SNI in packet");
return 0;
}
}
return 1;
}
#undef PREFIX
#endif