#include "dnscrypt.h" struct SignedCert * cert_build_cert(const uint8_t *crypt_publickey, int cert_file_expire_seconds, int use_xchacha20) { 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; if (use_xchacha20) { signed_cert->version_major[1] = 2; } else { signed_cert->version_major[1] = 1; } signed_cert->version_minor[0] = 0; signed_cert->version_minor[1] = 0; memset(signed_cert->signature, 0, sizeof signed_cert->signature); memcpy(signed_cert->server_publickey, crypt_publickey, crypto_box_PUBLICKEYBYTES); memcpy(signed_cert->magic_query, crypt_publickey, sizeof(signed_cert->magic_query)); if (use_xchacha20) { sodium_increment(signed_cert->magic_query, sizeof signed_cert->magic_query); } uint32_t ts_begin = (uint32_t)time(NULL); uint32_t ts_end = ts_begin + cert_file_expire_seconds; if (cert_file_expire_seconds <= 0) { ts_begin = ts_end; } ts_begin = htonl(ts_begin); ts_end = htonl(ts_end); memcpy(signed_cert->serial, &ts_begin, 4); memcpy(signed_cert->ts_begin, &ts_begin, 4); memcpy(signed_cert->ts_end, &ts_end, 4); return signed_cert; } int cert_sign(struct SignedCert *signed_cert, const uint8_t *provider_secretkey) { unsigned long long signed_data_len = sizeof(struct SignedCert) - offsetof(struct SignedCert, server_publickey); return crypto_sign_detached(signed_cert->signature, NULL, signed_cert->server_publickey, signed_data_len, provider_secretkey); } 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("\""); }