-
Notifications
You must be signed in to change notification settings - Fork 74
/
cert.c
92 lines (82 loc) · 2.67 KB
/
cert.c
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
#include "dnscrypt.h"
struct SignedCert *
cert_build_cert(const uint8_t *crypt_publickey, int cert_file_expire_seconds,
int use_xchacha20)
{
struct SignedCert *signed_cert = malloc(sizeof(struct SignedCert));
if (!signed_cert)
return NULL;
memcpy(signed_cert->magic_cert, CERT_MAGIC_CERT, 4);
signed_cert->version_major[0] = 0;
if (use_xchacha20) {
signed_cert->version_major[1] = 2;
} else {
signed_cert->version_major[1] = 1;
}
signed_cert->version_minor[0] = 0;
signed_cert->version_minor[1] = 0;
memset(signed_cert->signature, 0, sizeof signed_cert->signature);
memcpy(signed_cert->server_publickey, crypt_publickey,
crypto_box_PUBLICKEYBYTES);
memcpy(signed_cert->magic_query, crypt_publickey,
sizeof(signed_cert->magic_query));
if (use_xchacha20) {
sodium_increment(signed_cert->magic_query, sizeof signed_cert->magic_query);
}
uint32_t ts_begin = (uint32_t)time(NULL);
uint32_t ts_end = ts_begin + cert_file_expire_seconds;
if (cert_file_expire_seconds <= 0) {
ts_begin = ts_end;
}
ts_begin = htonl(ts_begin);
ts_end = htonl(ts_end);
memcpy(signed_cert->serial, &ts_begin, 4);
memcpy(signed_cert->ts_begin, &ts_begin, 4);
memcpy(signed_cert->ts_end, &ts_end, 4);
return signed_cert;
}
int
cert_sign(struct SignedCert *signed_cert, const uint8_t *provider_secretkey)
{
unsigned long long signed_data_len =
sizeof(struct SignedCert) - offsetof(struct SignedCert,
server_publickey);
return crypto_sign_detached(signed_cert->signature, NULL,
signed_cert->server_publickey, signed_data_len,
provider_secretkey);
}
void
cert_display_txt_record_tinydns(struct SignedCert *signed_cert)
{
size_t i = (size_t) 0U;
int c;
fputs("'2.dnscrypt-cert:", stdout);
while (i < sizeof(struct SignedCert)) {
c = (int)*((const uint8_t *) signed_cert + i);
if (isprint(c) && c != ':' && c != '\\' && c != '&' && c != '<'
&& c != '>') {
putchar(c);
} else {
printf("\\%03o", c);
}
i++;
}
puts(":86400");
}
void
cert_display_txt_record(struct SignedCert *signed_cert)
{
size_t i = (size_t) 0U;
int c;
fputs("2.dnscrypt-cert\t86400\tIN\tTXT\t\"", stdout);
while (i < sizeof(struct SignedCert)) {
c = (int)*((const uint8_t *) signed_cert + i);
if (isprint(c) && c != '"' && c != '\\') {
putchar(c);
} else {
printf("\\%03d", c);
}
i++;
}
puts("\"");
}