void curvecpr_chicago_new (struct curvecpr_chicago *chicago) { curvecpr_bytes_zero(chicago, sizeof(struct curvecpr_chicago)); curvecpr_chicago_refresh_clock(chicago); chicago->rtt_latest = 0; chicago->rtt_average = 0; chicago->rtt_deviation = 0; chicago->rtt_lowwater = 0; chicago->rtt_highwater = 0; chicago->rtt_timeout = 1000000000; chicago->seen_recent_high = 0; chicago->seen_recent_low = 0; chicago->seen_older_high = 0; chicago->seen_older_low = 0; chicago->rtt_phase = 0; chicago->wr_rate = 1000000000; chicago->ns_last_update = chicago->clock; chicago->ns_last_edge = 0; chicago->ns_last_doubling = 0; chicago->ns_last_panic = 0; }
static int _handle_client_message (struct curvecpr_server *server, struct curvecpr_session *s, void *priv, const struct curvecpr_packet_client_message *p, const unsigned char *buf, size_t num) { const struct curvecpr_server_cf *cf = &server->cf; unsigned char nonce[24]; unsigned char data[1120]; crypto_uint64 unpacked_nonce = curvecpr_bytes_unpack_uint64(p->nonce); if (unpacked_nonce <= s->their_session_nonce) return -EINVAL; curvecpr_bytes_copy(nonce, "CurveCP-client-M", 16); curvecpr_bytes_copy(nonce + 16, p->nonce, 8); curvecpr_bytes_zero(data, 16); curvecpr_bytes_copy(data + 16, buf, num); if (crypto_box_open_afternm(data, data, num + 16, nonce, s->my_session_their_session_key)) return -EINVAL; s->their_session_nonce = unpacked_nonce; curvecpr_session_set_priv(s, priv); if (cf->ops.recv(server, s, data + 32, num - 16)) return -EINVAL; return 0; }
void curvecpr_server_new (struct curvecpr_server *server, const struct curvecpr_server_cf *cf) { curvecpr_bytes_zero(server, sizeof(struct curvecpr_server)); /* Copy in the configuration. */ if (cf) curvecpr_bytes_copy(&server->cf, cf, sizeof(struct curvecpr_server_cf)); /* Generate brand new temporal keys. */ randombytes(server->my_temporal_key, sizeof(server->my_temporal_key)); randombytes(server->my_last_temporal_key, sizeof(server->my_last_temporal_key)); }
void curvecpr_client_new (struct curvecpr_client *client, const struct curvecpr_client_cf *cf) { curvecpr_bytes_zero(client, sizeof(struct curvecpr_client)); /* Copy in the configuration. */ if (cf) curvecpr_bytes_copy(&client->cf, cf, sizeof(struct curvecpr_client_cf)); /* Initialize session. */ curvecpr_session_new(&client->session); client->negotiated = CURVECPR_CLIENT_PENDING; }
static int _handle_initiate (struct curvecpr_server *server, struct curvecpr_session *s, void *priv, const struct curvecpr_packet_initiate *p, const unsigned char *buf, size_t num) { const struct curvecpr_server_cf *cf = &server->cf; unsigned char nonce[24]; unsigned char data[sizeof(struct curvecpr_packet_initiate_box) + 640]; if (s != NULL) { /* Update existing client. */ crypto_uint64 unpacked_nonce = curvecpr_bytes_unpack_uint64(p->nonce); if (unpacked_nonce <= s->their_session_nonce) return -EINVAL; curvecpr_bytes_copy(nonce, "CurveCP-client-I", 16); curvecpr_bytes_copy(nonce + 16, p->nonce, 8); curvecpr_bytes_zero(data, 16); curvecpr_bytes_copy(data + 16, buf, num); if (crypto_box_open_afternm(data, data, num + 16, nonce, s->my_session_their_session_key)) return -EINVAL; s->their_session_nonce = unpacked_nonce; curvecpr_session_set_priv(s, priv); if (cf->ops.recv(server, s, data + sizeof(struct curvecpr_packet_initiate_box), num + 16 - sizeof(struct curvecpr_packet_initiate_box))) return -EINVAL; return 0; } else { struct curvecpr_session s_new, *s_new_stored; const struct curvecpr_packet_initiate_box *p_box; /* Register new client. */ curvecpr_bytes_copy(nonce, "minute-k", 8); curvecpr_bytes_copy(nonce + 8, p->cookie, 16); /* We can reuse data; the cookie will fit into it. */ curvecpr_bytes_zero(data, 16); curvecpr_bytes_copy(data + 16, p->cookie + 16, 80); /* Validate cookie. */ if (crypto_secretbox_open(data, data, 96, nonce, server->my_temporal_key)) { curvecpr_bytes_zero(data, 16); curvecpr_bytes_copy(data + 16, p->cookie + 16, 80); if (crypto_secretbox_open(data, data, 96, nonce, server->my_last_temporal_key)) return -EINVAL; } if (!curvecpr_bytes_equal(p->client_session_pk, data + 32, 32)) return -EINVAL; /* Cookie is valid; set up keys. */ curvecpr_session_new(&s_new); curvecpr_bytes_copy(s_new.their_session_pk, data + 32, 32); curvecpr_bytes_copy(s_new.my_session_sk, data + 64, 32); crypto_box_beforenm(s_new.my_session_their_session_key, s_new.their_session_pk, s_new.my_session_sk); curvecpr_bytes_copy(nonce, "CurveCP-client-I", 16); curvecpr_bytes_copy(nonce + 16, p->nonce, 8); curvecpr_bytes_zero(data, 16); curvecpr_bytes_copy(data + 16, buf, num); if (crypto_box_open_afternm(data, data, num + 16, nonce, s_new.my_session_their_session_key)) return -EINVAL; p_box = (struct curvecpr_packet_initiate_box *)data; /* Attempt to validate this client. */ { unsigned char vouch[64]; curvecpr_bytes_copy(s_new.their_global_pk, p_box->client_global_pk, 32); crypto_box_beforenm(s_new.my_global_their_global_key, s_new.their_global_pk, cf->my_global_sk); curvecpr_bytes_copy(nonce, "CurveCPV", 8); curvecpr_bytes_copy(nonce + 8, p_box->nonce, 16); curvecpr_bytes_zero(vouch, 16); curvecpr_bytes_copy(vouch + 16, p_box->vouch, 48); if (crypto_box_afternm(vouch, vouch, 64, nonce, s_new.my_global_their_global_key)) return -EINVAL; if (!curvecpr_bytes_equal(vouch + 32, s_new.their_session_pk, 32)) return -EINVAL; } /* All good, we can go ahead and submit the client for registration. */ s_new.their_session_nonce = curvecpr_bytes_unpack_uint64(p->nonce); curvecpr_bytes_copy(s_new.my_domain_name, p_box->server_domain_name, 256); curvecpr_session_set_priv(&s_new, priv); if (cf->ops.put_session(server, &s_new, &s_new_stored)) return -EINVAL; /* This can fail for a variety of reasons that are up to the delegate to determine, but two typical ones will be too many connections or an invalid domain name. */ /* Now the session is registered; we can send the encapsulated message. */ if (cf->ops.recv(server, s_new_stored, data + sizeof(struct curvecpr_packet_initiate_box), num + 16 - sizeof(struct curvecpr_packet_initiate_box))) return -EINVAL; return 0; } }
static int _handle_hello (struct curvecpr_server *server, void *priv, const struct curvecpr_packet_hello *p) { const struct curvecpr_server_cf *cf = &server->cf; struct curvecpr_session s; /* Used only as a temporary store to make what we're doing more clear. */ unsigned char nonce[24]; unsigned char data[96] = { 0 }; /* Dummy initialization. */ curvecpr_session_new(&s); curvecpr_session_set_priv(&s, priv); /* Verify initial connection parameters. */ curvecpr_bytes_copy(s.their_session_pk, p->client_session_pk, 32); crypto_box_beforenm(s.my_global_their_session_key, s.their_session_pk, cf->my_global_sk); curvecpr_bytes_copy(nonce, "CurveCP-client-H", 16); curvecpr_bytes_copy(nonce + 16, p->nonce, 8); curvecpr_bytes_copy(data + 16, p->box, 80); if (crypto_box_open_afternm(data, data, 96, nonce, s.my_global_their_session_key)) return -EINVAL; /* Set up session keys. */ crypto_box_keypair(s.my_session_pk, s.my_session_sk); /* Prepare to send a cookie packet. */ { struct curvecpr_packet_cookie po; struct curvecpr_packet_cookie_box po_box; curvecpr_bytes_zero(po_box._, 32); curvecpr_bytes_copy(po_box.server_session_pk, s.my_session_pk, 32); /* Generate the cookie. */ curvecpr_bytes_zero(po_box.cookie, 32); curvecpr_bytes_copy(po_box.cookie + 32, s.their_session_pk, 32); curvecpr_bytes_copy(po_box.cookie + 64, s.my_session_sk, 32); /* Encrypt the cookie with our global nonce and temporary key. */ curvecpr_bytes_copy(nonce, "minute-k", 8); if (cf->ops.next_nonce(server, nonce + 8, 16)) return -EINVAL; crypto_secretbox(po_box.cookie, po_box.cookie, 96, nonce, server->my_temporal_key); curvecpr_bytes_copy(po_box.cookie, nonce + 8, 16); /* Now encrypt the whole box. */ curvecpr_bytes_copy(nonce, "CurveCPK", 8); crypto_box_afternm((unsigned char *)&po_box, (const unsigned char *)&po_box, sizeof(struct curvecpr_packet_cookie_box), nonce, s.my_global_their_session_key); /* Build the rest of the packet. */ curvecpr_bytes_copy(po.id, "RL3aNMXK", 8); curvecpr_bytes_copy(po.client_extension, p->client_extension, 16); curvecpr_bytes_copy(po.server_extension, cf->my_extension, 16); curvecpr_bytes_copy(po.nonce, nonce + 8, 16); curvecpr_bytes_copy(po.box, (const unsigned char *)&po_box + 16, 144); if (cf->ops.send(server, &s, (const unsigned char *)&po, sizeof(struct curvecpr_packet_cookie))) return -EINVAL; } return 0; }