Exemple #1
0
static void
cert_query_cb(void *arg, int status, int timeouts, unsigned char *abuf,
              int alen)
{
    Bincert               *bincert = NULL;
    ProxyContext          *proxy_context = arg;
    struct ares_txt_reply *txt_out;
    struct ares_txt_reply *txt_out_current;

    (void) timeouts;
    DNSCRYPT_PROXY_CERTS_UPDATE_RECEIVED();
    if (status != ARES_SUCCESS ||
        ares_parse_txt_reply(abuf, alen, &txt_out) != ARES_SUCCESS) {
        logger_noformat(proxy_context, LOG_ERR,
                        "Unable to retrieve server certificates");
        cert_reschedule_query_after_failure(proxy_context);
        DNSCRYPT_PROXY_CERTS_UPDATE_ERROR_COMMUNICATION();
        return;
    }
    txt_out_current = txt_out;
    while (txt_out_current != NULL) {
        cert_open_bincert(proxy_context,
                          (const SignedBincert *) txt_out_current->txt,
                          txt_out_current->length, &bincert);
        txt_out_current = txt_out_current->next;
    }
    ares_free_data(txt_out);
    if (bincert == NULL) {
        logger_noformat(proxy_context, LOG_ERR,
                        "No useable certificates found");
        cert_reschedule_query_after_failure(proxy_context);
        DNSCRYPT_PROXY_CERTS_UPDATE_ERROR_NOCERTS();
        return;
    }
    COMPILER_ASSERT(sizeof proxy_context->resolver_publickey ==
                    sizeof bincert->server_publickey);
    memcpy(proxy_context->resolver_publickey, bincert->server_publickey,
           sizeof proxy_context->resolver_publickey);
    COMPILER_ASSERT(sizeof proxy_context->dnscrypt_magic_query ==
                    sizeof bincert->magic_query);
    memcpy(proxy_context->dnscrypt_magic_query, bincert->magic_query,
           sizeof proxy_context->dnscrypt_magic_query);
    cert_print_server_key(proxy_context);
    dnscrypt_client_init_magic_query(&proxy_context->dnscrypt_client,
                                     bincert->magic_query);
    memset(bincert, 0, sizeof *bincert);
    free(bincert);
    dnscrypt_client_init_nmkey(&proxy_context->dnscrypt_client,
                               proxy_context->resolver_publickey);
    dnscrypt_proxy_start_listeners(proxy_context);
    proxy_context->cert_updater.query_retry_step = 0U;
    cert_reschedule_query_after_success(proxy_context);
    DNSCRYPT_PROXY_CERTS_UPDATE_DONE((unsigned char *)
                                     proxy_context->resolver_publickey);
}
Exemple #2
0
static void
cert_query_cb(int result, char type, int count, int ttl,
              void * const txt_records_, void * const arg)
{
    Bincert                 *bincert = NULL;
    ProxyContext            *proxy_context = arg;
    const struct txt_record *txt_records = txt_records_;
    int                      i = 0;

    (void) type;
    (void) ttl;
    DNSCRYPT_PROXY_CERTS_UPDATE_RECEIVED();
    evdns_base_free(proxy_context->cert_updater.evdns_base, 0);
    proxy_context->cert_updater.evdns_base = NULL;
    if (result != DNS_ERR_NONE) {
        logger_noformat(proxy_context, LOG_ERR,
                        "Unable to retrieve server certificates");
        cert_reschedule_query_after_failure(proxy_context);
        DNSCRYPT_PROXY_CERTS_UPDATE_ERROR_COMMUNICATION();
        return;
    }
    assert(count >= 0);
    while (i < count) {
        cert_open_bincert(proxy_context,
                          (const SignedBincert *) txt_records[i].txt,
                          txt_records[i].len, &bincert);
        i++;
    }
    if (bincert == NULL) {
        logger_noformat(proxy_context, LOG_ERR,
                        "No useable certificates found");
        cert_reschedule_query_after_failure(proxy_context);
        DNSCRYPT_PROXY_CERTS_UPDATE_ERROR_NOCERTS();
        if (proxy_context->test_only) {
            exit(DNSCRYPT_EXIT_CERT_NOCERTS);
        }
        return;
    }
    if (proxy_context->test_only != 0) {
        const uint32_t now_u32 = (uint32_t) time(NULL);
        uint32_t       ts_end;

        memcpy(&ts_end, bincert->ts_end, sizeof ts_end);
        ts_end = htonl(ts_end);

        if (ts_end < (uint32_t) proxy_context->test_cert_margin ||
            now_u32 > ts_end - (uint32_t) proxy_context->test_cert_margin) {
            logger_noformat(proxy_context, LOG_WARNING,
                            "The certificate is not valid for the given safety margin");
            DNSCRYPT_PROXY_CERTS_UPDATE_ERROR_NOCERTS();
            exit(DNSCRYPT_EXIT_CERT_MARGIN);
        }
    }
    COMPILER_ASSERT(sizeof proxy_context->resolver_publickey ==
                    sizeof bincert->server_publickey);
    memcpy(proxy_context->resolver_publickey, bincert->server_publickey,
           sizeof proxy_context->resolver_publickey);
    COMPILER_ASSERT(sizeof proxy_context->dnscrypt_magic_query ==
                    sizeof bincert->magic_query);
    memcpy(proxy_context->dnscrypt_magic_query, bincert->magic_query,
           sizeof proxy_context->dnscrypt_magic_query);
    cert_print_bincert_info(proxy_context, bincert);
    cert_print_server_key(proxy_context);
    dnscrypt_client_init_magic_query(&proxy_context->dnscrypt_client,
                                     bincert->magic_query);
    memset(bincert, 0, sizeof *bincert);
    free(bincert);
    if (proxy_context->test_only) {
        DNSCRYPT_PROXY_CERTS_UPDATE_DONE((unsigned char *)
                                         proxy_context->resolver_publickey);
        exit(0);
    }
    dnscrypt_client_init_nmkey(&proxy_context->dnscrypt_client,
                               proxy_context->resolver_publickey);
    dnscrypt_proxy_start_listeners(proxy_context);
    proxy_context->cert_updater.query_retry_step = 0U;
    cert_reschedule_query_after_success(proxy_context);
    DNSCRYPT_PROXY_CERTS_UPDATE_DONE((unsigned char *)
                                     proxy_context->resolver_publickey);
}