7 # include <sys/socket.h>
8 # include <arpa/inet.h>
18 #include <event2/dns.h>
19 #include <event2/event.h>
23 #include "dnscrypt_proxy.h"
29 static int cert_updater_update(ProxyContext
* const proxy_context
);
32 cert_parse_version(ProxyContext
* const proxy_context
,
33 const SignedBincert
* const signed_bincert
,
34 const size_t signed_bincert_len
)
36 if (signed_bincert_len
<= (size_t) (signed_bincert
->signed_data
-
37 signed_bincert
->magic_cert
) ||
38 memcmp(signed_bincert
->magic_cert
, CERT_MAGIC_CERT
,
39 sizeof signed_bincert
->magic_cert
) != 0) {
40 logger_noformat(proxy_context
, LOG_DEBUG
,
41 "TXT record with no certificates received");
44 if (signed_bincert
->version_major
[0] != 0U ||
45 signed_bincert
->version_major
[1] != 1U) {
46 logger_noformat(proxy_context
, LOG_WARNING
,
47 "Unsupported certificate version");
54 cert_parse_bincert(ProxyContext
* const proxy_context
,
55 const Bincert
* const bincert
,
56 const Bincert
* const previous_bincert
)
59 memcpy(&serial
, bincert
->serial
, sizeof serial
);
60 serial
= htonl(serial
);
61 logger(proxy_context
, LOG_INFO
,
62 "Server certificate #%" PRIu32
" received", serial
);
65 memcpy(&ts_begin
, bincert
->ts_begin
, sizeof ts_begin
);
66 ts_begin
= htonl(ts_begin
);
69 memcpy(&ts_end
, bincert
->ts_end
, sizeof ts_end
);
70 ts_end
= htonl(ts_end
);
72 uint32_t now_u32
= (uint32_t) time(NULL
);
74 if (now_u32
< ts_begin
) {
75 logger_noformat(proxy_context
, LOG_INFO
,
76 "This certificate has not been activated yet");
79 if (now_u32
> ts_end
) {
80 logger_noformat(proxy_context
, LOG_INFO
,
81 "This certificate has expired");
84 logger_noformat(proxy_context
, LOG_INFO
, "This certificate looks valid");
85 if (previous_bincert
== NULL
) {
89 uint32_t previous_serial
;
90 memcpy(&previous_serial
, previous_bincert
->serial
, sizeof previous_serial
);
91 previous_serial
= htonl(previous_serial
);
92 if (previous_serial
> serial
) {
93 logger(proxy_context
, LOG_INFO
, "Certificate #%" PRIu32
" "
94 "has been superseded by certificate #%" PRIu32
,
95 previous_serial
, serial
);
98 logger(proxy_context
, LOG_INFO
,
99 "This certificate supersedes certificate #%" PRIu32
,
106 cert_open_bincert(ProxyContext
* const proxy_context
,
107 const SignedBincert
* const signed_bincert
,
108 const size_t signed_bincert_len
,
109 Bincert
** const bincert_p
)
112 unsigned long long bincert_data_len_ul
;
114 size_t signed_data_len
;
116 if (cert_parse_version(proxy_context
,
117 signed_bincert
, signed_bincert_len
) != 0) {
118 DNSCRYPT_PROXY_CERTS_UPDATE_ERROR_COMMUNICATION();
121 bincert_size
= signed_bincert_len
;
122 if ((bincert
= malloc(bincert_size
)) == NULL
) {
123 DNSCRYPT_PROXY_CERTS_UPDATE_ERROR_COMMUNICATION();
126 assert(signed_bincert_len
>= (size_t) (signed_bincert
->signed_data
-
127 signed_bincert
->magic_cert
));
128 signed_data_len
= signed_bincert_len
-
129 (size_t) (signed_bincert
->signed_data
- signed_bincert
->magic_cert
);
130 assert(bincert_size
- (size_t) (bincert
->server_publickey
-
131 bincert
->magic_cert
) == signed_data_len
);
132 if (crypto_sign_ed25519_open(bincert
->server_publickey
, &bincert_data_len_ul
,
133 signed_bincert
->signed_data
, signed_data_len
,
134 proxy_context
->provider_publickey
) != 0) {
136 logger_noformat(proxy_context
, LOG_ERR
,
137 "Suspicious certificate received");
138 DNSCRYPT_PROXY_CERTS_UPDATE_ERROR_SECURITY();
141 if (cert_parse_bincert(proxy_context
, bincert
, *bincert_p
) != 0) {
142 memset(bincert
, 0, sizeof *bincert
);
146 if (*bincert_p
!= NULL
) {
147 memset(*bincert_p
, 0, sizeof **bincert_p
);
150 *bincert_p
= bincert
;
156 cert_print_server_key(ProxyContext
* const proxy_context
)
158 char fingerprint
[80U];
160 dnscrypt_key_to_fingerprint(fingerprint
,
161 proxy_context
->resolver_publickey
);
162 logger(proxy_context
, LOG_INFO
,
163 "Server key fingerprint is %s", fingerprint
);
167 cert_timer_cb(evutil_socket_t handle
, const short event
,
168 void * const proxy_context_
)
170 ProxyContext
* const proxy_context
= proxy_context_
;
174 logger_noformat(proxy_context
, LOG_INFO
,
175 "Refetching server certificates");
176 cert_updater_update(proxy_context
);
180 cert_reschedule_query(ProxyContext
* const proxy_context
,
181 const time_t query_retry_delay
)
183 CertUpdater
*cert_updater
= &proxy_context
->cert_updater
;
185 if (evtimer_pending(cert_updater
->cert_timer
, NULL
)) {
188 const struct timeval tv
= { .tv_sec
= query_retry_delay
, .tv_usec
= 0 };
189 evtimer_add(cert_updater
->cert_timer
, &tv
);
193 cert_reschedule_query_after_failure(ProxyContext
* const proxy_context
)
195 CertUpdater
*cert_updater
= &proxy_context
->cert_updater
;
196 time_t query_retry_delay
;
198 if (evtimer_pending(cert_updater
->cert_timer
, NULL
)) {
201 query_retry_delay
= (time_t)
202 (CERT_QUERY_RETRY_MIN_DELAY
+
203 (time_t) cert_updater
->query_retry_step
*
204 (CERT_QUERY_RETRY_MAX_DELAY
- CERT_QUERY_RETRY_MIN_DELAY
) /
205 CERT_QUERY_RETRY_STEPS
);
206 if (cert_updater
->query_retry_step
< CERT_QUERY_RETRY_STEPS
) {
207 cert_updater
->query_retry_step
++;
209 cert_reschedule_query(proxy_context
, query_retry_delay
);
210 DNSCRYPT_PROXY_CERTS_UPDATE_RETRY();
214 cert_reschedule_query_after_success(ProxyContext
* const proxy_context
)
216 if (evtimer_pending(proxy_context
->cert_updater
.cert_timer
, NULL
)) {
219 cert_reschedule_query(proxy_context
, (time_t)
220 CERT_QUERY_RETRY_DELAY_AFTER_SUCCESS_MIN_DELAY
221 + (time_t) randombytes_uniform
222 (CERT_QUERY_RETRY_DELAY_AFTER_SUCCESS_JITTER
));
226 cert_query_cb(int result
, char type
, int count
, int ttl
,
227 void * const txt_records_
, void * const arg
)
229 Bincert
*bincert
= NULL
;
230 ProxyContext
*proxy_context
= arg
;
231 const struct txt_record
*txt_records
= txt_records_
;
236 DNSCRYPT_PROXY_CERTS_UPDATE_RECEIVED();
237 evdns_base_free(proxy_context
->cert_updater
.evdns_base
, 0);
238 proxy_context
->cert_updater
.evdns_base
= NULL
;
239 if (result
!= DNS_ERR_NONE
) {
240 logger_noformat(proxy_context
, LOG_ERR
,
241 "Unable to retrieve server certificates");
242 cert_reschedule_query_after_failure(proxy_context
);
243 DNSCRYPT_PROXY_CERTS_UPDATE_ERROR_COMMUNICATION();
248 cert_open_bincert(proxy_context
,
249 (const SignedBincert
*) txt_records
[i
].txt
,
250 txt_records
[i
].len
, &bincert
);
253 if (bincert
== NULL
) {
254 logger_noformat(proxy_context
, LOG_ERR
,
255 "No useable certificates found");
256 cert_reschedule_query_after_failure(proxy_context
);
257 DNSCRYPT_PROXY_CERTS_UPDATE_ERROR_NOCERTS();
260 COMPILER_ASSERT(sizeof proxy_context
->resolver_publickey
==
261 sizeof bincert
->server_publickey
);
262 memcpy(proxy_context
->resolver_publickey
, bincert
->server_publickey
,
263 sizeof proxy_context
->resolver_publickey
);
264 COMPILER_ASSERT(sizeof proxy_context
->dnscrypt_magic_query
==
265 sizeof bincert
->magic_query
);
266 memcpy(proxy_context
->dnscrypt_magic_query
, bincert
->magic_query
,
267 sizeof proxy_context
->dnscrypt_magic_query
);
268 cert_print_server_key(proxy_context
);
269 dnscrypt_client_init_magic_query(&proxy_context
->dnscrypt_client
,
270 bincert
->magic_query
);
271 memset(bincert
, 0, sizeof *bincert
);
273 dnscrypt_client_init_nmkey(&proxy_context
->dnscrypt_client
,
274 proxy_context
->resolver_publickey
);
275 dnscrypt_proxy_start_listeners(proxy_context
);
276 proxy_context
->cert_updater
.query_retry_step
= 0U;
277 cert_reschedule_query_after_success(proxy_context
);
278 DNSCRYPT_PROXY_CERTS_UPDATE_DONE((unsigned char *)
279 proxy_context
->resolver_publickey
);
283 cert_updater_init(ProxyContext
* const proxy_context
)
285 CertUpdater
*cert_updater
= &proxy_context
->cert_updater
;
287 memset(cert_updater
, 0, sizeof *cert_updater
);
288 assert(proxy_context
->event_loop
!= NULL
);
289 assert(cert_updater
->cert_timer
== NULL
);
290 if ((cert_updater
->cert_timer
=
291 evtimer_new(proxy_context
->event_loop
,
292 cert_timer_cb
, proxy_context
)) == NULL
) {
295 cert_updater
->query_retry_step
= 0U;
296 cert_updater
->evdns_base
= NULL
;
302 cert_updater_update(ProxyContext
* const proxy_context
)
304 CertUpdater
*cert_updater
= &proxy_context
->cert_updater
;
306 DNSCRYPT_PROXY_CERTS_UPDATE_START();
307 if (cert_updater
->evdns_base
!= NULL
) {
308 evdns_base_free(cert_updater
->evdns_base
, 0);
310 if ((cert_updater
->evdns_base
=
311 evdns_base_new(proxy_context
->event_loop
, 0)) == NULL
) {
314 if (evdns_base_nameserver_sockaddr_add(cert_updater
->evdns_base
,
316 &proxy_context
->resolver_sockaddr
,
317 proxy_context
->resolver_sockaddr_len
,
318 DNS_QUERY_NO_SEARCH
) != 0) {
321 if (proxy_context
->tcp_only
!= 0) {
322 (void) evdns_base_nameserver_ip_add(cert_updater
->evdns_base
,
323 proxy_context
->resolver_ip
);
325 if (evdns_base_resolve_txt(cert_updater
->evdns_base
,
326 proxy_context
->provider_name
,
329 proxy_context
) == NULL
) {
336 cert_updater_start(ProxyContext
* const proxy_context
)
338 evdns_set_random_init_fn(NULL
);
339 evdns_set_random_bytes_fn(randombytes_buf
);
340 cert_updater_update(proxy_context
);
346 cert_updater_stop(ProxyContext
* const proxy_context
)
348 CertUpdater
* const cert_updater
= &proxy_context
->cert_updater
;
350 assert(cert_updater
->cert_timer
!= NULL
);
351 evtimer_del(cert_updater
->cert_timer
);
355 cert_updater_free(ProxyContext
* const proxy_context
)
357 CertUpdater
* const cert_updater
= &proxy_context
->cert_updater
;
359 event_free(cert_updater
->cert_timer
);
360 cert_updater
->cert_timer
= NULL
;
361 if (cert_updater
->evdns_base
!= NULL
) {
362 evdns_base_free(cert_updater
->evdns_base
, 0);
363 cert_updater
->evdns_base
= NULL
;