Skip to content

Commit e33d842

Browse files
Miscellaneous
* Add support for the SSL client certificate TLV * Add support for the SSL-related TLVs for key exchange group and signature * Add missing unit tests for some types
1 parent 77ae04d commit e33d842

4 files changed

Lines changed: 311 additions & 23 deletions

File tree

examples/client_server.c

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,42 @@
1010

1111
#include "../src/proxy_protocol.h"
1212

13+
/* Self-signed EC (prime256v1) X.509 DER certificate, CN=test */
14+
static const uint8_t client_cert_der[] = {
15+
0x30, 0x82, 0x01, 0x72, 0x30, 0x82, 0x01, 0x19, 0xa0, 0x03, 0x02, 0x01,
16+
0x02, 0x02, 0x14, 0x27, 0xd1, 0xb7, 0x26, 0x8d, 0xd6, 0x95, 0x5b, 0xda,
17+
0xe3, 0x58, 0x8d, 0x19, 0xbe, 0x88, 0x84, 0x32, 0xcc, 0x62, 0xea, 0x30,
18+
0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30,
19+
0x0f, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x04,
20+
0x74, 0x65, 0x73, 0x74, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x36, 0x30, 0x33,
21+
0x31, 0x31, 0x31, 0x34, 0x34, 0x36, 0x34, 0x39, 0x5a, 0x17, 0x0d, 0x33,
22+
0x36, 0x30, 0x33, 0x30, 0x38, 0x31, 0x34, 0x34, 0x36, 0x34, 0x39, 0x5a,
23+
0x30, 0x0f, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c,
24+
0x04, 0x74, 0x65, 0x73, 0x74, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a,
25+
0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce,
26+
0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x88, 0x7b, 0xd1, 0x60,
27+
0x92, 0x37, 0x00, 0x86, 0x8c, 0x3d, 0x06, 0x42, 0xf4, 0x1b, 0x9f, 0x27,
28+
0x9e, 0xca, 0x74, 0xc5, 0xdb, 0xfd, 0x6f, 0x82, 0x39, 0x61, 0x70, 0xb9,
29+
0x0b, 0xe8, 0x14, 0x07, 0xc6, 0x30, 0xea, 0xd8, 0xbb, 0x01, 0x05, 0x5f,
30+
0x07, 0x6a, 0xe8, 0x1f, 0x2c, 0x4b, 0x43, 0x8f, 0x4d, 0x87, 0xa1, 0xad,
31+
0xc6, 0x19, 0x05, 0xae, 0x2b, 0x09, 0x60, 0x55, 0x00, 0x4a, 0xe7, 0xb4,
32+
0xa3, 0x53, 0x30, 0x51, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04,
33+
0x16, 0x04, 0x14, 0xf9, 0x84, 0xb4, 0x02, 0xba, 0x3c, 0xa8, 0xa9, 0x19,
34+
0x86, 0x9e, 0x3c, 0xe6, 0x77, 0x79, 0x39, 0x9a, 0x7f, 0x1e, 0x53, 0x30,
35+
0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
36+
0xf9, 0x84, 0xb4, 0x02, 0xba, 0x3c, 0xa8, 0xa9, 0x19, 0x86, 0x9e, 0x3c,
37+
0xe6, 0x77, 0x79, 0x39, 0x9a, 0x7f, 0x1e, 0x53, 0x30, 0x0f, 0x06, 0x03,
38+
0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01,
39+
0xff, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03,
40+
0x02, 0x03, 0x47, 0x00, 0x30, 0x44, 0x02, 0x20, 0x2a, 0x7e, 0xf8, 0xf6,
41+
0x4c, 0x99, 0x27, 0x70, 0x24, 0x9b, 0x51, 0x8f, 0x29, 0x23, 0x9b, 0x41,
42+
0x01, 0x93, 0x0f, 0x77, 0x84, 0xba, 0x08, 0x34, 0xee, 0x23, 0xa6, 0xaf,
43+
0xe5, 0xdc, 0x7d, 0xf3, 0x02, 0x20, 0x53, 0xf2, 0x42, 0xd6, 0xab, 0xca,
44+
0x9a, 0x66, 0xfe, 0x3e, 0x49, 0x77, 0xf6, 0xe4, 0xea, 0xcb, 0xff, 0xde,
45+
0x1e, 0xf7, 0x2b, 0x97, 0x40, 0x99, 0xde, 0x2e, 0x9b, 0x15, 0x5c, 0x87,
46+
0xb7, 0x7c
47+
};
48+
1349
int main(void)
1450
{
1551
int32_t error = ERR_NULL;
@@ -84,7 +120,7 @@ int main(void)
84120
pp_info_in_v2.pp2_info.pp2_ssl_info.cert_verified = 1;
85121
/* Add SSL TLVs */
86122
/* IMPORTANT: Always clear the pp_info to be passed in pp_create_hdr() because TLVs are allocated in heap. Otherwise memory will be leaked */
87-
if (!pp_info_add_ssl(&pp_info_in_v2, "TLSv1.2", "ECDHE-RSA-AES128-GCM-SHA256", "SHA256", "RSA2048", (const uint8_t*) "example.com", 11))
123+
if (!pp_info_add_ssl(&pp_info_in_v2, "TLSv1.2", "ECDHE-RSA-AES128-GCM-SHA256", "SHA256", "RSA2048", "secp256r1", "rsa_pss_rsae_sha256", (const uint8_t*) "example.com", 11, client_cert_der, sizeof(client_cert_der)))
88124
{
89125
fprintf(stderr, "pp_info_add_ssl() failed\n");
90126
pp_info_clear(&pp_info_in_v2);
@@ -120,10 +156,11 @@ int main(void)
120156
}
121157
else
122158
{
123-
uint16_t length, cn_length;
159+
uint16_t length, cn_length, client_cert_length;
124160
uint32_t linkid;
125161
const uint8_t *azure_linkid = pp_info_get_azure_linkid(&pp_info_out, &length);
126162
const uint8_t *cn = pp_info_get_ssl_cn(&pp_info_out, &cn_length);
163+
const uint8_t *client_cert = pp_info_get_ssl_client_cert(&pp_info_out, &client_cert_length);
127164
memcpy(&linkid, azure_linkid, length);
128165
printf("%d bytes PROXY protocol header:\n"
129166
"\tAzure Link ID: %u\n"
@@ -132,7 +169,10 @@ int main(void)
132169
"\tSSL cipher: %s\n"
133170
"\tSSL sig_alg: %s\n"
134171
"\tSSL key_alg: %s\n"
172+
"\tSSL group: %s\n"
173+
"\tSSL sig_scheme: %s\n"
135174
"\tSSL CN: %.*s\n"
175+
"\tSSL client_cert: %s\n"
136176
"\t%s %s %hu %hu\n",
137177
rc, linkid,
138178
/* In case CRC32c is wrong then rc < 0 => pp_strerror(rc) at previous block will print the error */
@@ -141,7 +181,10 @@ int main(void)
141181
pp_info_get_ssl_cipher(&pp_info_out, &length),
142182
pp_info_get_ssl_sig_alg(&pp_info_out, &length),
143183
pp_info_get_ssl_key_alg(&pp_info_out, &length),
184+
pp_info_get_ssl_group(&pp_info_out, &length),
185+
pp_info_get_ssl_sig_scheme(&pp_info_out, &length),
144186
cn_length, cn,
187+
client_cert ? "present" : "not present",
145188
pp_info_out.src_addr, pp_info_out.dst_addr,
146189
pp_info_out.src_port, pp_info_out.dst_port);
147190
}

src/proxy_protocol.c

Lines changed: 66 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -111,11 +111,14 @@ typedef union
111111
#define PP2_TYPE_NOOP 0x04
112112
#define PP2_TYPE_UNIQUE_ID 0x05
113113
#define PP2_TYPE_SSL 0x20
114-
#define PP2_SUBTYPE_SSL_VERSION 0x21
115-
#define PP2_SUBTYPE_SSL_CN 0x22
116-
#define PP2_SUBTYPE_SSL_CIPHER 0x23
117-
#define PP2_SUBTYPE_SSL_SIG_ALG 0x24
118-
#define PP2_SUBTYPE_SSL_KEY_ALG 0x25
114+
#define PP2_SUBTYPE_SSL_VERSION 0x21
115+
#define PP2_SUBTYPE_SSL_CN 0x22
116+
#define PP2_SUBTYPE_SSL_CIPHER 0x23
117+
#define PP2_SUBTYPE_SSL_SIG_ALG 0x24
118+
#define PP2_SUBTYPE_SSL_KEY_ALG 0x25
119+
#define PP2_SUBTYPE_SSL_GROUP 0x26
120+
#define PP2_SUBTYPE_SSL_SIG_SCHEME 0x27
121+
#define PP2_SUBTYPE_SSL_CLIENT_CERT 0x28
119122
#define PP2_TYPE_NETNS 0x30
120123
/* Custom TLVs */
121124
#define PP2_TYPE_AWS 0xEA
@@ -318,7 +321,7 @@ static void pp_info_add_subtype_ssl(uint8_t *value, uint16_t *index, uint8_t sub
318321
*index += length;
319322
}
320323

321-
uint8_t pp_info_add_ssl(pp_info_t *pp_info, const char *version, const char *cipher, const char *sig_alg, const char *key_alg, const uint8_t *cn, uint16_t cn_value_len)
324+
uint8_t pp_info_add_ssl(pp_info_t *pp_info, const char *version, const char *cipher, const char *sig_alg, const char *key_alg, const char *group, const char *sig_scheme, const uint8_t *cn, uint16_t cn_value_len, const uint8_t *client_cert, uint16_t client_cert_len)
322325
{
323326
const pp2_ssl_info_t *pp2_ssl_info = &pp_info->pp2_info.pp2_ssl_info;
324327
uint8_t client = pp2_ssl_info->ssl | pp2_ssl_info->cert_in_connection << 1 | pp2_ssl_info->cert_in_connection << 2;
@@ -327,16 +330,46 @@ uint8_t pp_info_add_ssl(pp_info_t *pp_info, const char *version, const char *cip
327330
size_t cipher_value_len = cipher ? strlen(cipher) : 0;
328331
size_t sig_alg_value_len = sig_alg ? strlen(sig_alg) : 0;
329332
size_t key_alg_value_len = key_alg ? strlen(key_alg) : 0;
330-
size_t length = sizeof(client) + sizeof(verify)
331-
+ sizeof_pp2_tlv_t + version_value_len
332-
+ sizeof_pp2_tlv_t + cipher_value_len
333-
+ sizeof_pp2_tlv_t + sig_alg_value_len
334-
+ sizeof_pp2_tlv_t + key_alg_value_len
335-
+ sizeof_pp2_tlv_t + cn_value_len;
333+
size_t group_value_len = group ? strlen(group) : 0;
334+
size_t sig_scheme_value_len = sig_scheme ? strlen(sig_scheme) : 0;
335+
size_t length = sizeof(client) + sizeof(verify);
336336
uint16_t index = 0;
337337
uint8_t *value = NULL;
338338
uint8_t rc;
339339

340+
if (version_value_len)
341+
{
342+
length += sizeof_pp2_tlv_t + version_value_len;
343+
}
344+
if (cipher_value_len)
345+
{
346+
length += sizeof_pp2_tlv_t + cipher_value_len;
347+
}
348+
if (sig_alg_value_len)
349+
{
350+
length += sizeof_pp2_tlv_t + sig_alg_value_len;
351+
}
352+
if (key_alg_value_len)
353+
{
354+
length += sizeof_pp2_tlv_t + key_alg_value_len;
355+
}
356+
if (group_value_len)
357+
{
358+
length += sizeof_pp2_tlv_t + group_value_len;
359+
}
360+
if (sig_scheme_value_len)
361+
{
362+
length += sizeof_pp2_tlv_t + sig_scheme_value_len;
363+
}
364+
if (cn_value_len && cn)
365+
{
366+
length += sizeof_pp2_tlv_t + cn_value_len;
367+
}
368+
if (client_cert_len && client_cert)
369+
{
370+
length += sizeof_pp2_tlv_t + client_cert_len;
371+
}
372+
340373
if (length > UINT16_MAX)
341374
{
342375
return 0;
@@ -350,7 +383,10 @@ uint8_t pp_info_add_ssl(pp_info_t *pp_info, const char *version, const char *cip
350383
pp_info_add_subtype_ssl(value, &index, PP2_SUBTYPE_SSL_CIPHER, (uint16_t) cipher_value_len, cipher);
351384
pp_info_add_subtype_ssl(value, &index, PP2_SUBTYPE_SSL_SIG_ALG, (uint16_t) sig_alg_value_len, sig_alg);
352385
pp_info_add_subtype_ssl(value, &index, PP2_SUBTYPE_SSL_KEY_ALG, (uint16_t) key_alg_value_len, key_alg);
386+
pp_info_add_subtype_ssl(value, &index, PP2_SUBTYPE_SSL_GROUP, (uint16_t) group_value_len, group);
387+
pp_info_add_subtype_ssl(value, &index, PP2_SUBTYPE_SSL_SIG_SCHEME, (uint16_t) sig_scheme_value_len, sig_scheme);
353388
pp_info_add_subtype_ssl(value, &index, PP2_SUBTYPE_SSL_CN, cn_value_len, cn);
389+
pp_info_add_subtype_ssl(value, &index, PP2_SUBTYPE_SSL_CLIENT_CERT, client_cert_len, client_cert);
354390
rc = tlv_array_append_tlv_new(&pp_info->pp2_info.tlv_array, PP2_TYPE_SSL, (uint16_t) length, value);
355391
free(value);
356392
return rc;
@@ -475,6 +511,21 @@ const uint8_t *pp_info_get_ssl_key_alg(const pp_info_t *pp_info, uint16_t *lengt
475511
return pp_info_get_tlv_value(pp_info, PP2_SUBTYPE_SSL_KEY_ALG, 0, length);
476512
}
477513

514+
const uint8_t *pp_info_get_ssl_group(const pp_info_t *pp_info, uint16_t *length)
515+
{
516+
return pp_info_get_tlv_value(pp_info, PP2_SUBTYPE_SSL_GROUP, 0, length);
517+
}
518+
519+
const uint8_t *pp_info_get_ssl_sig_scheme(const pp_info_t *pp_info, uint16_t *length)
520+
{
521+
return pp_info_get_tlv_value(pp_info, PP2_SUBTYPE_SSL_SIG_SCHEME, 0, length);
522+
}
523+
524+
const uint8_t *pp_info_get_ssl_client_cert(const pp_info_t *pp_info, uint16_t *length)
525+
{
526+
return pp_info_get_tlv_value(pp_info, PP2_SUBTYPE_SSL_CLIENT_CERT, 0, length);
527+
}
528+
478529
const uint8_t *pp_info_get_netns(const pp_info_t *pp_info, uint16_t *length)
479530
{
480531
return pp_info_get_tlv_value(pp_info, PP2_TYPE_NETNS, 0, length);
@@ -1074,12 +1125,15 @@ static int32_t pp2_parse_hdr(const uint8_t *buffer, uint32_t buffer_length, pp_i
10741125
case PP2_SUBTYPE_SSL_CIPHER: /* US-ASCII */
10751126
case PP2_SUBTYPE_SSL_SIG_ALG: /* US-ASCII */
10761127
case PP2_SUBTYPE_SSL_KEY_ALG: /* US-ASCII */
1128+
case PP2_SUBTYPE_SSL_GROUP: /* US-ASCII */
1129+
case PP2_SUBTYPE_SSL_SIG_SCHEME: /* US-ASCII */
10771130
if (!tlv_array_append_tlv_new_usascii(&pp_info->pp2_info.tlv_array, pp2_sub_tlv_ssl->type, pp2_sub_tlv_ssl_len, pp2_sub_tlv_ssl->value))
10781131
{
10791132
return -ERR_HEAP_ALLOC;
10801133
}
10811134
break;
10821135
case PP2_SUBTYPE_SSL_CN: /* UTF8 */
1136+
case PP2_SUBTYPE_SSL_CLIENT_CERT: /* raw binary */
10831137
if (!tlv_array_append_tlv_new(&pp_info->pp2_info.tlv_array, pp2_sub_tlv_ssl->type, pp2_sub_tlv_ssl_len, pp2_sub_tlv_ssl->value))
10841138
{
10851139
return -ERR_HEAP_ALLOC;

src/proxy_protocol.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ typedef struct
140140
uint8_t pp_info_add_alpn(pp_info_t *pp_info, uint16_t length, const uint8_t *alpn);
141141
uint8_t pp_info_add_authority(pp_info_t *pp_info, uint16_t length, const uint8_t *host_name);
142142
uint8_t pp_info_add_unique_id(pp_info_t *pp_info, uint16_t length, const uint8_t *unique_id);
143-
uint8_t pp_info_add_ssl(pp_info_t *pp_info, const char *version, const char *cipher, const char *sig_alg, const char *key_alg, const uint8_t *cn, uint16_t cn_len);
143+
uint8_t pp_info_add_ssl(pp_info_t *pp_info, const char *version, const char *cipher, const char *sig_alg, const char *key_alg, const char *group, const char *sig_scheme, const uint8_t *cn, uint16_t cn_len, const uint8_t *client_cert, uint16_t client_cert_len);
144144
uint8_t pp_info_add_netns(pp_info_t *pp_info, const char *netns);
145145
uint8_t pp_info_add_aws_vpce_id(pp_info_t *pp_info, const char *vpce_id);
146146
uint8_t pp_info_add_azure_linkid(pp_info_t *pp_info, uint32_t linkid);
@@ -161,6 +161,9 @@ const uint8_t *pp_info_get_ssl_cn(const pp_info_t *pp_info, uint16_t *length);
161161
const uint8_t *pp_info_get_ssl_cipher(const pp_info_t *pp_info, uint16_t *length);
162162
const uint8_t *pp_info_get_ssl_sig_alg(const pp_info_t *pp_info, uint16_t *length);
163163
const uint8_t *pp_info_get_ssl_key_alg(const pp_info_t *pp_info, uint16_t *length);
164+
const uint8_t *pp_info_get_ssl_group(const pp_info_t *pp_info, uint16_t *length);
165+
const uint8_t *pp_info_get_ssl_sig_scheme(const pp_info_t *pp_info, uint16_t *length);
166+
const uint8_t *pp_info_get_ssl_client_cert(const pp_info_t *pp_info, uint16_t *length);
164167
const uint8_t *pp_info_get_netns(const pp_info_t *pp_info, uint16_t *length);
165168
const uint8_t *pp_info_get_aws_vpce_id(const pp_info_t *pp_info, uint16_t *length);
166169
const uint8_t *pp_info_get_azure_linkid(const pp_info_t *pp_info, uint16_t *length);

0 commit comments

Comments
 (0)