-
Notifications
You must be signed in to change notification settings - Fork 74
/
Copy pathcert.c
110 lines (100 loc) · 3.18 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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#include "dnscrypt.h"
struct SignedCert *
cert_build_cert(const uint8_t *crypt_publickey, int cert_file_expire_days)
{
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;
signed_cert->version_major[1] = 1;
signed_cert->version_minor[0] = 0;
signed_cert->version_minor[1] = 0;
memcpy(signed_cert->server_publickey, crypt_publickey,
crypto_box_PUBLICKEYBYTES);
memcpy(signed_cert->magic_query, CERT_MAGIC_HEADER,
sizeof(signed_cert->magic_query));
memcpy(signed_cert->serial, "0001", 4);
uint32_t ts_begin = (uint32_t)time(NULL);
uint32_t ts_end = ts_begin + cert_file_expire_days * 24 * 3600;
if (cert_file_expire_days <= 0) {
ts_begin = ts_end;
}
ts_begin = htonl(ts_begin);
ts_end = htonl(ts_end);
memcpy(signed_cert->ts_begin, &ts_begin, 4);
memcpy(signed_cert->ts_end, &ts_end, 4);
memset(signed_cert->end, 0, sizeof(signed_cert->end));
return signed_cert;
}
int
cert_sign(struct SignedCert *signed_cert, const uint8_t *provider_secretkey)
{
struct SignedCert cert;
unsigned long long crypted_signed_data_len = 0;
unsigned long long signed_data_len =
sizeof(struct SignedCert) - offsetof(struct SignedCert,
server_publickey) -
sizeof(signed_cert->end);
memcpy(&cert, signed_cert, sizeof cert);
if (crypto_sign_ed25519
(signed_cert->server_publickey,
&crypted_signed_data_len,
cert.server_publickey, signed_data_len,
provider_secretkey) != 0) {
return -1;
}
return 0;
}
int
cert_unsign(struct SignedCert *signed_cert, const uint8_t *provider_secretkey)
{
unsigned long long crypted_signed_data_len = 0;
unsigned long long signed_data_len =
sizeof(struct SignedCert) - offsetof(struct SignedCert,
server_publickey) -
sizeof(signed_cert->end);
if (crypto_sign_ed25519_open
(signed_cert->server_publickey,
&crypted_signed_data_len,
signed_cert->server_publickey, signed_data_len,
provider_secretkey) != 0) {
return -1;
}
return 0;
}
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("\"");
}