예제 #1
0
/**
 * 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;
}
예제 #2
0
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);
}
예제 #3
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);
}
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;
}
예제 #6
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;
    }
}
예제 #7
0
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;
}
예제 #8
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;
}
예제 #9
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];
}
예제 #10
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 * 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];
}
예제 #11
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);
}