/** * proto_conn_drop(conn_cookie): * Drop connection and frees memory associated with ${conn_cookie}. Return * success or failure. */ int proto_conn_drop(void * conn_cookie) { struct conn_state * C = conn_cookie; int rc; /* Close the incoming connection. */ close(C->s); /* Close the outgoing connection if it is open. */ if (C->t != -1) close(C->t); /* Stop connecting if a connection is in progress. */ if (C->connect_cookie != NULL) network_connect_cancel(C->connect_cookie); /* Free the target addresses if we haven't already done so. */ sock_addr_freelist(C->sas); /* Stop handshaking if a handshake is in progress. */ if (C->handshake_cookie != NULL) proto_handshake_cancel(C->handshake_cookie); /* Kill timeouts if they are pending. */ if (C->connect_timeout_cookie != NULL) events_timer_cancel(C->connect_timeout_cookie); if (C->handshake_timeout_cookie != NULL) events_timer_cancel(C->handshake_timeout_cookie); /* Free protocol keys. */ proto_crypt_free(C->k_f); proto_crypt_free(C->k_r); /* Shut down pipes. */ if (C->pipe_f != NULL) proto_pipe_cancel(C->pipe_f); if (C->pipe_r != NULL) proto_pipe_cancel(C->pipe_r); /* Notify the upstream that we've dropped a connection. */ rc = (C->callback_dead)(C->cookie); /* Free the connection cookie. */ free(C); /* Return success/fail status. */ return (rc); }
/** * proto_crypt_mkkeys(K, nonce_l, nonce_r, yh_r, x, nofps, decr, eh_c, eh_s): * Using the protocol secret ${K}, the local and remote nonces ${nonce_l} and * ${nonce_r}, the remote MACed diffie-hellman handshake parameter ${yh_r}, * and the local diffie-hellman secret ${x}, generate the keys ${eh_c} and * ${eh_s}. If ${nofps} is non-zero, we are performing weak handshaking and * y_SC is set to 1 rather than being computed. If ${decr} is non-zero, * "local" == "S" and "remote" == "C"; otherwise the assignments are opposite. */ int proto_crypt_mkkeys(const struct proto_secret * K, const uint8_t nonce_l[PCRYPT_NONCE_LEN], const uint8_t nonce_r[PCRYPT_NONCE_LEN], const uint8_t yh_r[PCRYPT_YH_LEN], const uint8_t x[PCRYPT_X_LEN], int nofps, int decr, struct proto_keys ** eh_c, struct proto_keys ** eh_s) { uint8_t nonce_y[PCRYPT_NONCE_LEN * 2 + CRYPTO_DH_KEYLEN]; uint8_t dk_2[128]; const uint8_t * nonce_c, * nonce_s; /* Copy in nonces (in the right order). */ nonce_c = decr ? nonce_r : nonce_l; nonce_s = decr ? nonce_l : nonce_r; memcpy(&nonce_y[0], nonce_c, PCRYPT_NONCE_LEN); memcpy(&nonce_y[PCRYPT_NONCE_LEN], nonce_s, PCRYPT_NONCE_LEN); /* Are we bypassing the diffie-hellman computation? */ if (nofps) { /* We sent y_l = 1, so y_SC is also 1. */ memset(&nonce_y[PCRYPT_NONCE_LEN * 2], 0, CRYPTO_DH_KEYLEN - 1); nonce_y[PCRYPT_NONCE_LEN * 2 + CRYPTO_DH_KEYLEN - 1] = 1; } else { /* Perform the diffie-hellman computation. */ if (crypto_dh_compute(yh_r, x, &nonce_y[PCRYPT_NONCE_LEN * 2])) goto err0; } /* Compute dk_2. */ PBKDF2_SHA256(K->K, 32, nonce_y, PCRYPT_NONCE_LEN * 2 + CRYPTO_DH_KEYLEN, 1, dk_2, 128); /* Create key structures. */ if ((*eh_c = mkkeypair(&dk_2[0])) == NULL) goto err0; if ((*eh_s = mkkeypair(&dk_2[64])) == NULL) goto err1; /* Success! */ return (0); err1: proto_crypt_free(*eh_c); err0: /* Failure! */ return (-1); }