/** * Notes: In order to avoid -Wint-to-pointer-cast and -Wpointer-to-int-cast * errors uintptr_t is to be used. */ inline void * jlongToPointer( jlong const p ) { COMPILER_ASSERT( sizeof(jlong) == 8 ) COMPILER_ASSERT( sizeof(unsigned long long) == 8 ) assert( (unsigned long long) p <= UINTPTR_MAX && "Got a non 32-bit pointer on a 32-bit system!!" ); return (unsigned long long) p <= UINTPTR_MAX ? (void*) (uintptr_t) p : NULL; }
int crypto_kx_keypair(unsigned char pk[crypto_kx_PUBLICKEYBYTES], unsigned char sk[crypto_kx_SECRETKEYBYTES]) { COMPILER_ASSERT(crypto_kx_SECRETKEYBYTES == crypto_scalarmult_SCALARBYTES); COMPILER_ASSERT(crypto_kx_PUBLICKEYBYTES == crypto_scalarmult_BYTES); randombytes_buf(sk, crypto_kx_SECRETKEYBYTES); return crypto_scalarmult_base(pk, sk); }
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); }
int crypto_pwhash_scryptsalsa208sha256_str( char out[crypto_pwhash_scryptsalsa208sha256_STRBYTES], const char *const passwd, unsigned long long passwdlen, unsigned long long opslimit, size_t memlimit) { uint8_t salt[crypto_pwhash_scryptsalsa208sha256_STRSALTBYTES]; char setting[crypto_pwhash_scryptsalsa208sha256_STRSETTINGBYTES + 1U]; escrypt_local_t escrypt_local; uint32_t N_log2; uint32_t p; uint32_t r; memset(out, 0, crypto_pwhash_scryptsalsa208sha256_STRBYTES); if (passwdlen > crypto_pwhash_scryptsalsa208sha256_PASSWD_MAX) { errno = EFBIG; /* LCOV_EXCL_LINE */ return -1; /* LCOV_EXCL_LINE */ } if (passwdlen < crypto_pwhash_scryptsalsa208sha256_PASSWD_MIN || pickparams(opslimit, memlimit, &N_log2, &p, &r) != 0) { errno = EINVAL; /* LCOV_EXCL_LINE */ return -1; /* LCOV_EXCL_LINE */ } randombytes_buf(salt, sizeof salt); if (escrypt_gensalt_r(N_log2, r, p, salt, sizeof salt, (uint8_t *) setting, sizeof setting) == NULL) { errno = EINVAL; /* LCOV_EXCL_LINE */ return -1; /* LCOV_EXCL_LINE */ } if (escrypt_init_local(&escrypt_local) != 0) { return -1; /* LCOV_EXCL_LINE */ } if (escrypt_r(&escrypt_local, (const uint8_t *) passwd, (size_t) passwdlen, (const uint8_t *) setting, (uint8_t *) out, crypto_pwhash_scryptsalsa208sha256_STRBYTES) == NULL) { /* LCOV_EXCL_START */ escrypt_free_local(&escrypt_local); errno = EINVAL; return -1; /* LCOV_EXCL_STOP */ } escrypt_free_local(&escrypt_local); COMPILER_ASSERT( SETTING_SIZE(crypto_pwhash_scryptsalsa208sha256_STRSALTBYTES) == crypto_pwhash_scryptsalsa208sha256_STRSETTINGBYTES); COMPILER_ASSERT( crypto_pwhash_scryptsalsa208sha256_STRSETTINGBYTES + 1U + crypto_pwhash_scryptsalsa208sha256_STRHASHBYTES_ENCODED + 1U == crypto_pwhash_scryptsalsa208sha256_STRBYTES); return 0; }
int crypto_aead_chacha20poly1305_ietf_decrypt_detached(unsigned char *m, unsigned char *nsec, const unsigned char *c, unsigned long long clen, const unsigned char *mac, const unsigned char *ad, unsigned long long adlen, const unsigned char *npub, const unsigned char *k) { crypto_onetimeauth_poly1305_state state; unsigned char block0[64U]; unsigned char slen[8U]; unsigned char computed_mac[crypto_aead_chacha20poly1305_ietf_ABYTES]; unsigned long long mlen; int ret; (void) nsec; crypto_stream_chacha20_ietf(block0, sizeof block0, npub, k); crypto_onetimeauth_poly1305_init(&state, block0); sodium_memzero(block0, sizeof block0); crypto_onetimeauth_poly1305_update(&state, ad, adlen); crypto_onetimeauth_poly1305_update(&state, _pad0, (0x10 - adlen) & 0xf); mlen = clen; crypto_onetimeauth_poly1305_update(&state, c, mlen); crypto_onetimeauth_poly1305_update(&state, _pad0, (0x10 - mlen) & 0xf); STORE64_LE(slen, (uint64_t) adlen); crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen); STORE64_LE(slen, (uint64_t) mlen); crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen); crypto_onetimeauth_poly1305_final(&state, computed_mac); sodium_memzero(&state, sizeof state); COMPILER_ASSERT(sizeof computed_mac == 16U); ret = crypto_verify_16(computed_mac, mac); sodium_memzero(computed_mac, sizeof computed_mac); if (m == NULL) { return ret; } if (ret != 0) { memset(m, 0, mlen); return -1; } crypto_stream_chacha20_ietf_xor_ic(m, c, mlen, npub, 1U, k); return 0; }
void dnscrypt_key_to_fingerprint(char fingerprint[80U], const uint8_t * const key) { const size_t fingerprint_size = 80U; size_t fingerprint_pos = (size_t) 0U; size_t key_pos = (size_t) 0U; COMPILER_ASSERT(crypto_box_PUBLICKEYBYTES == 32U); COMPILER_ASSERT(crypto_box_SECRETKEYBYTES == 32U); for (;;) { assert(fingerprint_size > fingerprint_pos); snprintf(&fingerprint[fingerprint_pos], fingerprint_size - fingerprint_pos, "%02X%02X", key[key_pos], key[key_pos + 1U]); key_pos += 2U; if (key_pos >= crypto_box_PUBLICKEYBYTES) { break; } fingerprint[fingerprint_pos + 4U] = ':'; fingerprint_pos += 5U; } }
int crypto_kx_server_session_keys(unsigned char rx[crypto_kx_SESSIONKEYBYTES], unsigned char tx[crypto_kx_SESSIONKEYBYTES], const unsigned char server_pk[crypto_kx_PUBLICKEYBYTES], const unsigned char server_sk[crypto_kx_SECRETKEYBYTES], const unsigned char client_pk[crypto_kx_PUBLICKEYBYTES]) { crypto_generichash_state h; unsigned char q[crypto_scalarmult_BYTES]; unsigned char keys[2 * crypto_kx_SESSIONKEYBYTES]; int i; if (rx == NULL) { rx = tx; } if (tx == NULL) { tx = rx; } if (rx == NULL) { sodium_misuse(); /* LCOV_EXCL_LINE */ } if (crypto_scalarmult(q, server_sk, client_pk) != 0) { return -1; } COMPILER_ASSERT(sizeof keys <= crypto_generichash_BYTES_MAX); crypto_generichash_init(&h, NULL, 0U, sizeof keys); crypto_generichash_update(&h, q, crypto_scalarmult_BYTES); sodium_memzero(q, sizeof q); crypto_generichash_update(&h, client_pk, crypto_kx_PUBLICKEYBYTES); crypto_generichash_update(&h, server_pk, crypto_kx_PUBLICKEYBYTES); crypto_generichash_final(&h, keys, sizeof keys); sodium_memzero(&h, sizeof h); for (i = 0; i < crypto_kx_SESSIONKEYBYTES; i++) { tx[i] = keys[i]; rx[i] = keys[i + crypto_kx_SESSIONKEYBYTES]; } sodium_memzero(keys, sizeof keys); return 0; }
int crypto_generichash_blake2b_init(crypto_generichash_blake2b_state *state, const unsigned char *key, const size_t keylen, const size_t outlen) { if (outlen <= 0U || outlen > BLAKE2B_OUTBYTES || keylen > BLAKE2B_KEYBYTES) { return -1; } assert(outlen <= UINT8_MAX); assert(keylen <= UINT8_MAX); COMPILER_ASSERT(sizeof(blake2b_state) <= sizeof *state); if (key == NULL || keylen <= 0U) { if (blake2b_init((blake2b_state *) (void *) state, (uint8_t) outlen) != 0) { return -1; /* LCOV_EXCL_LINE */ } } else if (blake2b_init_key((blake2b_state *) (void *) state, (uint8_t) outlen, key, (uint8_t) keylen) != 0) { return -1; /* LCOV_EXCL_LINE */ } return 0; }
//============================================================================ // These errors should only be used in debugging. They should not be shown // in release clients because they are not localized const wchar_t * NetErrorToString (ENetError code) { static const wchar_t* s_errors[] = { L"Success", // kNetSuccess L"Internal Error", // kNetErrInternalError L"No Response From Server", // kNetErrTimeout L"Invalid Server Data", // kNetErrBadServerData L"Age Not Found", // kNetErrAgeNotFound L"Network Connection Failed", // kNetErrConnectFailed L"Disconnected From Server", // kNetErrDisconnected L"File Not Found", // kNetErrFileNotFound L"Old Build", // kNetErrOldBuildId L"Remote Shutdown", // kNetErrRemoteShutdown L"Database Timeout", // kNetErrTimeoutOdbc L"Account Already Exists", // kNetErrAccountAlreadyExists L"Player Already Exists", // kNetErrPlayerAlreadyExists L"Account Not Found", // kNetErrAccountNotFound L"Player Not Found", // kNetErrPlayerNotFound L"Invalid Parameter", // kNetErrInvalidParameter L"Name Lookup Failed", // kNetErrNameLookupFailed L"Logged In Elsewhere", // kNetErrLoggedInElsewhere L"Vault Node Not Found", // kNetErrVaultNodeNotFound L"Max Players On Account", // kNetErrMaxPlayersOnAcct L"Authentication Failed", // kNetErrAuthenticationFailed L"State Object Not Found", // kNetErrStateObjectNotFound L"Login Denied", // kNetErrLoginDenied L"Circular Reference", // kNetErrCircularReference L"Account Not Activated", // kNetErrAccountNotActivated L"Key Already Used", // kNetErrKeyAlreadyUsed L"Key Not Found", // kNetErrKeyNotFound L"Activation Code Not Found", // kNetErrActivationCodeNotFound L"Player Name Invalid", // kNetErrPlayerNameInvalid L"Not Supported", // kNetErrNotSupported L"Service Forbidden", // kNetErrServiceForbidden L"Auth Token Too Old", // kNetErrAuthTokenTooOld L"Must Use GameTap Client", // kNetErrMustUseGameTapClient L"Too Many Failed Logins", // kNetErrTooManyFailedLogins L"GameTap: Connection Failed", // kNetErrGameTapConnectionFailed L"GameTap: Too Many Auth Options", // kNetErrGTTooManyAuthOptions L"GameTap: Missing Parameter", // kNetErrGTMissingParameter L"GameTap: Server Error", // kNetErrGTServerError L"Account has been banned", // kNetErrAccountBanned L"Account kicked by CCR", // kNetErrKickedByCCR L"Wrong score type for operation", // kNetErrScoreWrongType L"Not enough points", // kNetErrScoreNotEnoughPoints L"Non-fixed score already exists", // kNetErrScoreAlreadyExists L"No score data found", // kNetErrScoreNoDataFound L"Invite: Couldn't find player", // kNetErrInviteNoMatchingPlayer L"Invite: Too many hoods", // kNetErrInviteTooManyHoods L"Payments not up to date", // kNetErrNeedToPay L"Server Busy", // kNetErrServerBusy L"Vault Node Access Violation", // kNetErrVaultNodeAccessViolation }; COMPILER_ASSERT(arrsize(s_errors) == kNumNetErrors); if ((unsigned)code >= arrsize(s_errors)) { if (code == kNetPending) return L"Pending"; return L"Unknown Error"; } return s_errors[code]; }
//============================================================================ // These errors should only be used in debugging. They should not be shown // in release clients because they are not localized const wchar_t * NetErrorAsString (ENetError code) { static const wchar_t* s_errors[] = { L"kNetSuccess", L"kNetErrInternalError", L"kNetErrTimeout", L"kNetErrBadServerData", L"kNetErrAgeNotFound", L"kNetErrConnectFailed", L"kNetErrDisconnected", L"kNetErrFileNotFound", L"kNetErrOldBuildId", L"kNetErrRemoteShutdown", L"kNetErrTimeoutOdbc", L"kNetErrAccountAlreadyExists", L"kNetErrPlayerAlreadyExists", L"kNetErrAccountNotFound", L"kNetErrPlayerNotFound", L"kNetErrInvalidParameter", L"kNetErrNameLookupFailed", L"kNetErrLoggedInElsewhere", L"kNetErrVaultNodeNotFound", L"kNetErrMaxPlayersOnAcct", L"kNetErrAuthenticationFailed", L"kNetErrStateObjectNotFound", L"kNetErrLoginDenied", L"kNetErrCircularReference", L"kNetErrAccountNotActivated", L"kNetErrKeyAlreadyUsed", L"kNetErrKeyNotFound", L"kNetErrActivationCodeNotFound", L"kNetErrPlayerNameInvalid", L"kNetErrNotSupported", L"kNetErrServiceForbidden", L"kNetErrAuthTokenTooOld", L"kNetErrMustUseGameTapClient", L"kNetErrTooManyFailedLogins", L"kNetErrGameTapConnectionFailed", L"kNetErrGTTooManyAuthOptions", L"kNetErrGTMissingParameter", L"kNetErrGTServerError", L"kNetErrAccountBanned", L"kNetErrKickedByCCR", L"kNetErrScoreWrongType", L"kNetErrScoreNotEnoughPoints", L"kNetErrScoreAlreadyExists", L"kNetErrScoreNoDataFound", L"kNetErrInviteNoMatchingPlayer", L"kNetErrInviteTooManyHoods", L"kNetErrNeedToPay", L"kNetErrServerBusy", L"kNetErrVaultNodeAccessViolation", }; COMPILER_ASSERT(arrsize(s_errors) == kNumNetErrors); if ((unsigned)code >= arrsize(s_errors)) { if (code == kNetPending) return L"kNetPending"; return L"ErrUnknown"; } return s_errors[code]; }
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); }