11 #include <event2/dns.h>
12 #include <event2/event.h>
16 #include "crypto_sign_ed25519.h"
17 #include "dnscrypt_proxy.h"
20 #include "salsa20_random.h"
23 static int cert_updater_update(ProxyContext
* const proxy_context
);
26 cert_parse_version(ProxyContext
* const proxy_context
,
27 const SignedBincert
* const signed_bincert
,
28 const size_t signed_bincert_len
)
30 if (signed_bincert_len
<= (size_t) (signed_bincert
->signed_data
-
31 signed_bincert
->magic_cert
) ||
32 memcmp(signed_bincert
->magic_cert
, CERT_MAGIC_CERT
,
33 sizeof signed_bincert
->magic_cert
) != 0) {
34 logger_noformat(proxy_context
, LOG_DEBUG
,
35 "TXT record with no certificates received");
38 if (signed_bincert
->version_major
[0] != 0U ||
39 signed_bincert
->version_major
[1] != 1U) {
40 logger_noformat(proxy_context
, LOG_WARNING
,
41 "Unsupported certificate version");
48 cert_parse_bincert(ProxyContext
* const proxy_context
,
49 const Bincert
* const bincert
,
50 const Bincert
* const previous_bincert
)
53 memcpy(&serial
, bincert
->serial
, sizeof serial
);
54 serial
= htonl(serial
);
55 logger(proxy_context
, LOG_INFO
, "Certificate #%lu received",
56 (unsigned long) serial
);
59 memcpy(&ts_begin
, bincert
->ts_begin
, sizeof ts_begin
);
60 ts_begin
= htonl(ts_begin
);
63 memcpy(&ts_end
, bincert
->ts_end
, sizeof ts_end
);
64 ts_end
= htonl(ts_end
);
66 uint32_t now_u32
= (uint32_t) time(NULL
);
68 if (now_u32
< ts_begin
) {
69 logger_noformat(proxy_context
, LOG_INFO
,
70 "Certificate not activated yet");
73 if (now_u32
> ts_end
) {
74 logger_noformat(proxy_context
, LOG_INFO
,
75 "Certificate expired");
78 logger_noformat(proxy_context
, LOG_INFO
, "Certificate valid");
79 if (previous_bincert
== NULL
) {
83 uint32_t previous_serial
;
84 memcpy(&previous_serial
, previous_bincert
->serial
, sizeof previous_serial
);
85 previous_serial
= htonl(previous_serial
);
86 if (previous_serial
> serial
) {
87 logger(proxy_context
, LOG_INFO
,
88 "Certificate #%lu has been superseded by certificate #%lu",
89 (unsigned long) previous_serial
, (unsigned long) serial
);
92 logger(proxy_context
, LOG_INFO
,
93 "This certificates supersedes certificate #%lu",
94 (unsigned long) previous_serial
);
100 cert_open_bincert(ProxyContext
* const proxy_context
,
101 const SignedBincert
* const signed_bincert
,
102 const size_t signed_bincert_len
,
103 Bincert
** const bincert_p
)
106 unsigned long long bincert_data_len_ul
;
108 size_t signed_data_len
;
110 if (cert_parse_version(proxy_context
,
111 signed_bincert
, signed_bincert_len
) != 0) {
112 DNSCRYPT_PROXY_CERTS_UPDATE_ERROR_COMMUNICATION();
115 bincert_size
= signed_bincert_len
;
116 if ((bincert
= malloc(bincert_size
)) == NULL
) {
117 DNSCRYPT_PROXY_CERTS_UPDATE_ERROR_COMMUNICATION();
120 assert(signed_bincert_len
>= (size_t) (signed_bincert
->signed_data
-
121 signed_bincert
->magic_cert
));
122 signed_data_len
= signed_bincert_len
-
123 (size_t) (signed_bincert
->signed_data
- signed_bincert
->magic_cert
);
124 assert(bincert_size
- (size_t) (bincert
->server_publickey
-
125 bincert
->magic_cert
) == signed_data_len
);
126 if (crypto_sign_ed25519_open(bincert
->server_publickey
, &bincert_data_len_ul
,
127 signed_bincert
->signed_data
, signed_data_len
,
128 proxy_context
->provider_publickey
) != 0) {
130 logger_noformat(proxy_context
, LOG_ERR
,
131 "Suspicious certificate received");
132 DNSCRYPT_PROXY_CERTS_UPDATE_ERROR_SECURITY();
135 if (cert_parse_bincert(proxy_context
, bincert
, *bincert_p
) != 0) {
136 memset(bincert
, 0, sizeof *bincert
);
140 if (*bincert_p
!= NULL
) {
141 memset(*bincert_p
, 0, sizeof **bincert_p
);
144 *bincert_p
= bincert
;
150 cert_print_server_key(ProxyContext
* const proxy_context
)
152 char fingerprint
[80U];
154 dnscrypt_key_to_fingerprint(fingerprint
,
155 proxy_context
->resolver_publickey
);
156 logger(proxy_context
, LOG_INFO
,
157 "Server Key genuine fingerprint is %s", fingerprint
);
161 cert_timer_cb(evutil_socket_t handle
, const short event
,
162 void * const proxy_context_
)
164 ProxyContext
* const proxy_context
= proxy_context_
;
168 logger_noformat(proxy_context
, LOG_INFO
,
169 "Refetching Certificates");
170 cert_updater_update(proxy_context
);
174 cert_reschedule_query(ProxyContext
* const proxy_context
,
175 const time_t query_retry_delay
)
177 CertUpdater
*cert_updater
= &proxy_context
->cert_updater
;
179 if (evtimer_pending(cert_updater
->cert_timer
, NULL
)) {
182 const struct timeval tv
= { .tv_sec
= query_retry_delay
, .tv_usec
= 0 };
183 evtimer_add(cert_updater
->cert_timer
, &tv
);
187 cert_reschedule_query_after_failure(ProxyContext
* const proxy_context
)
189 CertUpdater
*cert_updater
= &proxy_context
->cert_updater
;
190 time_t query_retry_delay
;
192 if (evtimer_pending(cert_updater
->cert_timer
, NULL
)) {
195 query_retry_delay
= (time_t)
196 (CERT_QUERY_RETRY_MIN_DELAY
+
197 (time_t) cert_updater
->query_retry_step
*
198 (CERT_QUERY_RETRY_MAX_DELAY
- CERT_QUERY_RETRY_MIN_DELAY
) /
199 CERT_QUERY_RETRY_STEPS
);
200 if (cert_updater
->query_retry_step
< CERT_QUERY_RETRY_STEPS
) {
201 cert_updater
->query_retry_step
++;
203 cert_reschedule_query(proxy_context
, query_retry_delay
);
204 DNSCRYPT_PROXY_CERTS_UPDATE_RETRY();
208 cert_reschedule_query_after_success(ProxyContext
* const proxy_context
)
210 if (evtimer_pending(proxy_context
->cert_updater
.cert_timer
, NULL
)) {
213 cert_reschedule_query(proxy_context
, (time_t)
214 CERT_QUERY_RETRY_DELAY_AFTER_SUCCESS_MIN_DELAY
215 + (time_t) salsa20_random_uniform
216 (CERT_QUERY_RETRY_DELAY_AFTER_SUCCESS_JITTER
));
220 cert_query_cb(int result
, char type
, int count
, int ttl
,
221 void * const txt_records_
, void * const arg
)
223 Bincert
*bincert
= NULL
;
224 ProxyContext
*proxy_context
= arg
;
225 const struct txt_record
*txt_records
= txt_records_
;
230 DNSCRYPT_PROXY_CERTS_UPDATE_RECEIVED();
231 evdns_base_free(proxy_context
->cert_updater
.evdns_base
, 0);
232 proxy_context
->cert_updater
.evdns_base
= NULL
;
233 if (result
!= DNS_ERR_NONE
) {
234 logger_noformat(proxy_context
, LOG_ERR
,
235 "Unable to retrieve server certificates");
236 cert_reschedule_query_after_failure(proxy_context
);
237 DNSCRYPT_PROXY_CERTS_UPDATE_ERROR_COMMUNICATION();
240 assert(count
== 0 || count
== 1);
242 cert_open_bincert(proxy_context
,
243 (const SignedBincert
*) txt_records
[i
].txt
,
244 txt_records
[i
].len
, &bincert
);
247 if (bincert
== NULL
) {
248 logger_noformat(proxy_context
, LOG_ERR
,
249 "No useable certificates found");
250 cert_reschedule_query_after_failure(proxy_context
);
251 DNSCRYPT_PROXY_CERTS_UPDATE_ERROR_NOCERTS();
254 COMPILER_ASSERT(sizeof proxy_context
->resolver_publickey
==
255 sizeof bincert
->server_publickey
);
256 memcpy(proxy_context
->resolver_publickey
, bincert
->server_publickey
,
257 sizeof proxy_context
->resolver_publickey
);
258 COMPILER_ASSERT(sizeof proxy_context
->dnscrypt_magic_query
==
259 sizeof bincert
->magic_query
);
260 memcpy(proxy_context
->dnscrypt_magic_query
, bincert
->magic_query
,
261 sizeof proxy_context
->dnscrypt_magic_query
);
262 cert_print_server_key(proxy_context
);
263 dnscrypt_client_init_magic_query(&proxy_context
->dnscrypt_client
,
264 bincert
->magic_query
);
265 memset(bincert
, 0, sizeof *bincert
);
267 dnscrypt_client_init_nmkey(&proxy_context
->dnscrypt_client
,
268 proxy_context
->resolver_publickey
);
269 dnscrypt_proxy_start_listeners(proxy_context
);
270 proxy_context
->cert_updater
.query_retry_step
= 0U;
271 cert_reschedule_query_after_success(proxy_context
);
272 DNSCRYPT_PROXY_CERTS_UPDATE_DONE((unsigned char *)
273 proxy_context
->resolver_publickey
);
277 cert_updater_init(ProxyContext
* const proxy_context
)
279 CertUpdater
*cert_updater
= &proxy_context
->cert_updater
;
281 memset(cert_updater
, 0, sizeof *cert_updater
);
282 assert(proxy_context
->event_loop
!= NULL
);
283 assert(cert_updater
->cert_timer
== NULL
);
284 if ((cert_updater
->cert_timer
=
285 evtimer_new(proxy_context
->event_loop
,
286 cert_timer_cb
, proxy_context
)) == NULL
) {
289 cert_updater
->query_retry_step
= 0U;
290 cert_updater
->evdns_base
= NULL
;
296 cert_updater_update(ProxyContext
* const proxy_context
)
298 CertUpdater
*cert_updater
= &proxy_context
->cert_updater
;
300 DNSCRYPT_PROXY_CERTS_UPDATE_START();
301 if (cert_updater
->evdns_base
!= NULL
) {
302 evdns_base_free(cert_updater
->evdns_base
, 0);
304 if ((cert_updater
->evdns_base
=
305 evdns_base_new(proxy_context
->event_loop
, 0)) == NULL
) {
308 if (evdns_base_nameserver_sockaddr_add(cert_updater
->evdns_base
,
310 &proxy_context
->resolver_sockaddr
,
311 proxy_context
->resolver_sockaddr_len
,
312 DNS_QUERY_NO_SEARCH
) != 0) {
315 if (proxy_context
->tcp_only
!= 0 &&
316 strcmp(proxy_context
->resolver_port
,
317 DNS_DEFAULT_STANDARD_DNS_PORT
) != 0) {
318 (void) evdns_base_nameserver_ip_add(cert_updater
->evdns_base
,
319 proxy_context
->resolver_ip
);
321 if (evdns_base_resolve_txt(cert_updater
->evdns_base
,
322 proxy_context
->provider_name
,
325 proxy_context
) == NULL
) {
332 cert_updater_start(ProxyContext
* const proxy_context
)
334 evdns_set_random_init_fn(NULL
);
335 evdns_set_random_bytes_fn(salsa20_random_buf
);
336 cert_updater_update(proxy_context
);
342 cert_updater_stop(ProxyContext
* const proxy_context
)
344 CertUpdater
* const cert_updater
= &proxy_context
->cert_updater
;
346 assert(cert_updater
->cert_timer
!= NULL
);
347 evtimer_del(cert_updater
->cert_timer
);
351 cert_updater_free(ProxyContext
* const proxy_context
)
353 CertUpdater
* const cert_updater
= &proxy_context
->cert_updater
;
355 event_free(cert_updater
->cert_timer
);
356 cert_updater
->cert_timer
= NULL
;
357 if (cert_updater
->evdns_base
!= NULL
) {
358 evdns_base_free(cert_updater
->evdns_base
, 0);
359 cert_updater
->evdns_base
= NULL
;