1 #include "dnscrypt.h"
2
3 struct SignedCert *
cert_build_cert(const uint8_t * crypt_publickey,int cert_file_expire_seconds,int use_xchacha20)4 cert_build_cert(const uint8_t *crypt_publickey, int cert_file_expire_seconds,
5 int use_xchacha20)
6 {
7 struct SignedCert *signed_cert = malloc(sizeof(struct SignedCert));
8 if (!signed_cert)
9 return NULL;
10
11 memcpy(signed_cert->magic_cert, CERT_MAGIC_CERT, 4);
12 signed_cert->version_major[0] = 0;
13 if (use_xchacha20) {
14 signed_cert->version_major[1] = 2;
15 } else {
16 signed_cert->version_major[1] = 1;
17 }
18 signed_cert->version_minor[0] = 0;
19 signed_cert->version_minor[1] = 0;
20
21 memset(signed_cert->signature, 0, sizeof signed_cert->signature);
22 memcpy(signed_cert->server_publickey, crypt_publickey,
23 crypto_box_PUBLICKEYBYTES);
24 memcpy(signed_cert->magic_query, crypt_publickey,
25 sizeof(signed_cert->magic_query));
26 if (use_xchacha20) {
27 sodium_increment(signed_cert->magic_query, sizeof signed_cert->magic_query);
28 }
29 uint32_t ts_begin = (uint32_t)time(NULL);
30 uint32_t ts_end = ts_begin + cert_file_expire_seconds;
31 if (cert_file_expire_seconds <= 0) {
32 ts_begin = ts_end;
33 }
34 ts_begin = htonl(ts_begin);
35 ts_end = htonl(ts_end);
36 memcpy(signed_cert->serial, &ts_begin, 4);
37 memcpy(signed_cert->ts_begin, &ts_begin, 4);
38 memcpy(signed_cert->ts_end, &ts_end, 4);
39
40 return signed_cert;
41 }
42
43 int
cert_sign(struct SignedCert * signed_cert,const uint8_t * provider_secretkey)44 cert_sign(struct SignedCert *signed_cert, const uint8_t *provider_secretkey)
45 {
46 unsigned long long signed_data_len =
47 sizeof(struct SignedCert) - offsetof(struct SignedCert,
48 server_publickey);
49
50 return crypto_sign_detached(signed_cert->signature, NULL,
51 signed_cert->server_publickey, signed_data_len,
52 provider_secretkey);
53 }
54
55 void
cert_display_txt_record_tinydns(struct SignedCert * signed_cert)56 cert_display_txt_record_tinydns(struct SignedCert *signed_cert)
57 {
58 size_t i = (size_t) 0U;
59 int c;
60
61 fputs("'2.dnscrypt-cert:", stdout);
62 while (i < sizeof(struct SignedCert)) {
63 c = (int)*((const uint8_t *) signed_cert + i);
64 if (isprint(c) && c != ':' && c != '\\' && c != '&' && c != '<'
65 && c != '>') {
66 putchar(c);
67 } else {
68 printf("\\%03o", c);
69 }
70 i++;
71 }
72 puts(":86400");
73 }
74
75 void
cert_display_txt_record(struct SignedCert * signed_cert)76 cert_display_txt_record(struct SignedCert *signed_cert)
77 {
78 size_t i = (size_t) 0U;
79 int c;
80
81 fputs("2.dnscrypt-cert\t86400\tIN\tTXT\t\"", stdout);
82 while (i < sizeof(struct SignedCert)) {
83 c = (int)*((const uint8_t *) signed_cert + i);
84 if (isprint(c) && c != '"' && c != '\\') {
85 putchar(c);
86 } else {
87 printf("\\%03d", c);
88 }
89 i++;
90 }
91 puts("\"");
92 }
93