ascii-chat
Binary v0.15.83-53-gb711d8720
Library lib/v0.3.2-701-gb711d8720
Video chat in your terminal
Loading...
Searching...
No Matches
security.c File Reference

Go to the source code of this file.

Functions

void acip_security_cleanup (acip_security_t *security)
asciichat_error_t acip_security_start (acip_security_t *security, acip_transport_t *transport)
asciichat_error_t acip_security_receive (acip_security_t *security, acip_transport_t *transport, packet_type_t type, const void *payload, size_t length)
bool acip_security_rekey_packet (uint16_t type)
asciichat_error_t acip_security_rekey_encode (unsigned flow, crypto_rekey_message_t type, const void *payload, size_t length, void *packet, size_t capacity, size_t *written)
asciichat_error_t acip_security_rekey_receive (crypto_rekey_session_t *session, acip_traffic_class_t flow, acip_delivery_t delivery, const void *packet, size_t length, uint64_t now, bool *consumed)
asciichat_error_t acip_security_rekey_seal (crypto_record_t *records, unsigned flow, crypto_rekey_message_t message, const void *payload, size_t length, uint8_t **wire, size_t *written)
asciichat_error_t acip_security_activate (acip_transport_t *transport)
asciichat_error_t acip_security_decrypt (crypto_context_t *crypto, unsigned flow, unsigned delivery, const void *payload, size_t length, uint8_t **output, size_t *written, uint64_t *sequence, bool *consumed)
asciichat_error_t acip_security_next_control (crypto_context_t *crypto, acip_traffic_class_t *flow, uint8_t **wire, size_t *length)
asciichat_error_t acip_security_flush (acip_transport_t *transport)
asciichat_error_t acip_security_request_rekey (acip_transport_t *transport)
asciichat_error_t acip_security_seal (crypto_context_t *crypto, acip_traffic_class_t flow, acip_delivery_t delivery, const void *packet, size_t length, uint8_t **output, size_t *written)
asciichat_error_t acip_security_open (crypto_context_t *crypto, acip_traffic_class_t flow, acip_delivery_t delivery, const void *packet, size_t length, uint8_t **output, size_t *written, uint64_t *sequence, bool *consumed)

Function Documentation

◆ acip_security_activate()

asciichat_error_t acip_security_activate ( acip_transport_t * transport)

Definition at line 178 of file lib/network/acip/security.c.

178 {
179 if (!transport)
180 return SET_ERRNO(ERROR_INVALID_PARAM, "Missing secure transport");
181 crypto_context_t *crypto = transport->crypto_ctx;
182 if (!crypto || !crypto->encrypt_data)
183 return ASCIICHAT_OK;
184 crypto_session_t *session = NULL;
185 asciichat_error_t result = crypto_session_lock(crypto, &session);
186 if (result == ASCIICHAT_OK) {
187 crypto_session_unlock(session);
188 atomic_store_bool(&transport->packet_security_active, true);
189 }
190 return result;
191}
#define SET_ERRNO(code,...)
asciichat_error_t
Error and exit codes - unified status values (0-255).
Definition error_codes.h:44
@ ASCIICHAT_OK
Definition error_codes.h:46
@ ERROR_INVALID_PARAM
struct crypto_session crypto_session_t
For crypto session, this is the live record that ties owner, mutex, records, rotation together....
void crypto_session_unlock(crypto_session_t *session)
asciichat_error_t crypto_session_lock(crypto_context_t *crypto, crypto_session_t **output)
atomic_t packet_security_active
Publishes the stable post-handshake crypto owner.
crypto_context_t * crypto_ctx
Optional encryption context.
Endpoint cryptographic state for handshake, packet protection, authentication, and rekeying.

References ASCIICHAT_OK, acip_transport::crypto_ctx, crypto_session_lock(), crypto_session_unlock(), crypto_context_t::encrypt_data, ERROR_INVALID_PARAM, acip_transport::packet_security_active, and SET_ERRNO.

Referenced by acip_security_receive(), and quic_transport_begin_security().

◆ acip_security_cleanup()

void acip_security_cleanup ( acip_security_t * security)

Definition at line 11 of file lib/network/acip/security.c.

11 {
12 if (!security)
13 return;
16}
void crypto_handshake_destroy(crypto_handshake_context_t *ctx)
Cleanup crypto handshake context with secure memory wiping.
#define SAFE_FREE(ptr)
Definition common.h:377
crypto_handshake_context_t handshake

References crypto_handshake_context_t::client_whitelist, crypto_handshake_destroy(), acip_security::handshake, and SAFE_FREE.

Referenced by acip_security_init_options(), and peer_crypto_destroy().

◆ acip_security_decrypt()

asciichat_error_t acip_security_decrypt ( crypto_context_t * crypto,
unsigned flow,
unsigned delivery,
const void * payload,
size_t length,
uint8_t ** output,
size_t * written,
uint64_t * sequence,
bool * consumed )

Definition at line 193 of file lib/network/acip/security.c.

195 {
196 if (!output || !written || !consumed)
197 return SET_ERRNO(ERROR_INVALID_PARAM, "Missing security receive output");
198 *output = NULL;
199 *written = 0;
200 *consumed = false;
201 crypto_session_t *session = NULL;
202 asciichat_error_t result = crypto_session_lock(crypto, &session);
203 if (result != ASCIICHAT_OK)
204 return result;
205 result = acip_packet_decrypt_payload(&session->records, flow, delivery, payload, length, output, written, sequence);
206 if (result == ASCIICHAT_OK) {
207 packet_header_t header;
208 memcpy(&header, *output, sizeof(header));
209 result = crypto_session_receive(session, session->records.last_receive_channel, delivery,
210 rekey_message(NET_TO_HOST_U16(header.type)), *output + sizeof(header),
211 *written - sizeof(header), time_get_ns(), consumed);
212 }
213 crypto_session_unlock(session);
214 if (result != ASCIICHAT_OK) {
215 buffer_release(*output);
216 *output = NULL;
217 *written = 0;
218 }
219 return result;
220}
#define buffer_release(data)
Definition buffer.h:91
#define NET_TO_HOST_U16(val)
Definition endian.h:111
asciichat_error_t crypto_session_receive(crypto_session_t *session, unsigned channel, unsigned delivery, crypto_rekey_message_t type, const void *payload, size_t length, uint64_t now, bool *consumed)
asciichat_error_t acip_packet_decrypt_payload(crypto_record_t *records, unsigned flow, unsigned delivery, const void *payload, size_t length, uint8_t **output, size_t *written, uint64_t *sequence)
Definition prepare.c:188
unsigned last_receive_channel
Definition record.h:26
Fixed prefix shared by every ACIP packet on the wire.
Definition packet.h:628

References acip_packet_decrypt_payload(), ASCIICHAT_OK, buffer_release, crypto_session_lock(), crypto_session_receive(), crypto_session_unlock(), ERROR_INVALID_PARAM, crypto_record::last_receive_channel, NET_TO_HOST_U16, crypto_session::records, and SET_ERRNO.

Referenced by acip_security_open(), client_decrypt_packet(), and packet_decrypt_envelope().

◆ acip_security_flush()

asciichat_error_t acip_security_flush ( acip_transport_t * transport)

Definition at line 248 of file lib/network/acip/security.c.

248 {
249 if (!transport || !atomic_load_bool(&transport->packet_security_active))
250 return ASCIICHAT_OK;
251 for (unsigned i = 0; i < CRYPTO_SESSION_MESSAGES; ++i) {
252 uint8_t *wire = NULL;
253 size_t length = 0;
255 asciichat_error_t result = acip_security_next_control(transport->crypto_ctx, &channel, &wire, &length);
256 if (result != ASCIICHAT_OK || !wire)
257 return result;
258 defer(buffer_release(wire));
259 socket_buffer_t slice = {wire, length};
260 acip_send_options_t options = {.traffic_class = channel, .delivery = ACIP_DELIVERY_RELIABLE};
261 if (transport->methods->sendv_ex)
262 result = transport->methods->sendv_ex(transport, &slice, 1, &options);
263 else if (transport->methods->sendv)
264 result = transport->methods->sendv(transport, &slice, 1);
265 else
266 result = transport->methods->send(transport, wire, length);
267 if (result != ASCIICHAT_OK)
268 return result;
269 }
270 return ASCIICHAT_OK;
271}
unsigned char uint8_t
Definition common.h:60
#define CRYPTO_SESSION_MESSAGES
asciichat_error_t acip_security_next_control(crypto_context_t *crypto, acip_traffic_class_t *flow, uint8_t **wire, size_t *length)
asciichat_error_t(* send)(acip_transport_t *transport, const void *data, size_t len)
Send data through this transport.
asciichat_error_t(* sendv)(acip_transport_t *transport, const socket_buffer_t *buffers, size_t count)
Custom destroy implementation (optional).
asciichat_error_t(* sendv_ex)(acip_transport_t *transport, const socket_buffer_t *buffers, size_t count, const acip_send_options_t *options)
const acip_transport_methods_t * methods
Method table (virtual functions).
acip_traffic_class_t
Definition traffic.h:5
@ ACIP_TRAFFIC_CONTROL
Definition traffic.h:6
@ ACIP_DELIVERY_RELIABLE
Definition traffic.h:12

References ACIP_DELIVERY_RELIABLE, acip_security_next_control(), ACIP_TRAFFIC_CONTROL, ASCIICHAT_OK, buffer_release, acip_transport::crypto_ctx, CRYPTO_SESSION_MESSAGES, acip_transport::methods, acip_transport::packet_security_active, acip_transport_methods_t::send, acip_transport_methods_t::sendv, and acip_transport_methods_t::sendv_ex.

Referenced by peer_crypto_tick().

◆ acip_security_next_control()

asciichat_error_t acip_security_next_control ( crypto_context_t * crypto,
acip_traffic_class_t * flow,
uint8_t ** wire,
size_t * length )

Definition at line 222 of file lib/network/acip/security.c.

223 {
224 if (!flow || !wire || !length)
225 return SET_ERRNO(ERROR_INVALID_PARAM, "Missing security output");
226 *wire = NULL;
227 *length = 0;
228 crypto_session_t *session = NULL;
229 asciichat_error_t result = crypto_session_lock(crypto, &session);
230 if (result != ASCIICHAT_OK)
231 return result;
232 defer(crypto_session_unlock(session));
233 result = crypto_session_tick(session, time_get_ns());
234 if (result == ASCIICHAT_OK && session->count) {
235 crypto_session_message_t *message = &session->messages[session->head];
236 *flow = (acip_traffic_class_t)message->channel;
237 result = acip_security_rekey_seal(&session->records, message->channel, message->type, message->payload,
238 message->length, wire, length);
239 if (result == ASCIICHAT_OK) {
240 memset(message, 0, sizeof(*message));
241 session->head = (session->head + 1) % CRYPTO_SESSION_MESSAGES;
242 --session->count;
243 }
244 }
245 return result;
246}
asciichat_error_t crypto_session_tick(crypto_session_t *session, uint64_t now)
asciichat_error_t acip_security_rekey_seal(crypto_record_t *records, unsigned flow, crypto_rekey_message_t message, const void *payload, size_t length, uint8_t **wire, size_t *written)
crypto_session_message_t messages[16]

References acip_security_rekey_seal(), ASCIICHAT_OK, crypto_session_message_t::channel, crypto_session::count, crypto_session_lock(), CRYPTO_SESSION_MESSAGES, crypto_session_tick(), crypto_session_unlock(), ERROR_INVALID_PARAM, crypto_session::head, crypto_session_message_t::length, crypto_session::messages, crypto_session_message_t::payload, crypto_session::records, SET_ERRNO, and crypto_session_message_t::type.

Referenced by acip_security_flush(), and browser_security_output().

◆ acip_security_open()

asciichat_error_t acip_security_open ( crypto_context_t * crypto,
acip_traffic_class_t flow,
acip_delivery_t delivery,
const void * packet,
size_t length,
uint8_t ** output,
size_t * written,
uint64_t * sequence,
bool * consumed )

Definition at line 296 of file lib/network/acip/security.c.

298 {
299 packet_header_t header;
300 asciichat_error_t result = packet_validate(packet, length, 0, &header);
301 if (result != ASCIICHAT_OK)
302 return result;
303 if (NET_TO_HOST_U16(header.type) != PACKET_TYPE_ENCRYPTED)
304 return SET_ERRNO(ERROR_CRYPTO, "Expected authenticated session record");
305 return acip_security_decrypt(crypto, flow, delivery, (const uint8_t *)packet + sizeof(header),
306 length - sizeof(header), output, written, sequence, consumed);
307}
@ ERROR_CRYPTO
Definition error_codes.h:93
asciichat_error_t packet_validate(const void *packet, size_t length, size_t limit, packet_header_t *output)
Definition packet.c:86
@ PACKET_TYPE_ENCRYPTED
Encrypted packet (after handshake completion).
Definition packet.h:355
asciichat_error_t acip_security_decrypt(crypto_context_t *crypto, unsigned flow, unsigned delivery, const void *payload, size_t length, uint8_t **output, size_t *written, uint64_t *sequence, bool *consumed)

References acip_security_decrypt(), ASCIICHAT_OK, ERROR_CRYPTO, NET_TO_HOST_U16, PACKET_TYPE_ENCRYPTED, packet_validate(), and SET_ERRNO.

Referenced by browser_security_packet(), and peer_crypto_receive().

◆ acip_security_receive()

asciichat_error_t acip_security_receive ( acip_security_t * security,
acip_transport_t * transport,
packet_type_t type,
const void * payload,
size_t length )

Definition at line 32 of file lib/network/acip/security.c.

33 {
34 if (!security || !transport || (!payload && length) || security->ready)
35 return SET_ERRNO(ERROR_INVALID_STATE, "Unexpected peer security packet");
36 crypto_handshake_context_t *ctx = &security->handshake;
38 if (!security->version_received) {
39 if (type != PACKET_TYPE_PROTOCOL_VERSION || length != sizeof(protocol_version_packet_t))
40 return SET_ERRNO(ERROR_NETWORK_PROTOCOL, "Expected peer security negotiation before media");
42 memcpy(&version, payload, sizeof(version));
43 uint8_t mode = version.supports_encryption;
47 return SET_ERRNO(ERROR_NETWORK_PROTOCOL, "Unsupported peer security protocol");
48 if (ctx->is_server) {
49 // Match secure WebSocket policy: defaults do not override a client's explicit no-encrypt.
50 if ((ctx->has_password || ctx->require_client_auth) && !ACIP_CRYPTO_HAS_AUTH(mode))
51 return SET_ERRNO(ERROR_CRYPTO_AUTH, "Peer omitted required authentication");
52 if (security->require_encryption && !ACIP_CRYPTO_HAS_ENCRYPT(mode))
53 return SET_ERRNO(ERROR_CRYPTO, "Peer omitted required encryption");
54 if (security->forbid_encryption && ACIP_CRYPTO_HAS_ENCRYPT(mode))
55 return SET_ERRNO(ERROR_CRYPTO, "Peer requires encryption but local policy disables it");
56 version.supports_encryption = mode;
57 result = packet_send_via_transport(transport, PACKET_TYPE_PROTOCOL_VERSION, &version, sizeof(version), 0);
58 if (result != ASCIICHAT_OK)
59 return result;
60 } else if ((mode & security->mode) != security->mode) {
61 return SET_ERRNO(ERROR_CRYPTO, "Peer attempted to downgrade requested security");
62 }
63 if (security->forbid_encryption && ACIP_CRYPTO_HAS_ENCRYPT(mode))
64 return SET_ERRNO(ERROR_CRYPTO, "Peer requires encryption but local policy disables it");
65 security->mode = mode;
66 security->version_received = true;
68 if (mode == ACIP_CRYPTO_NONE) {
70 security->ready = true;
71 return ASCIICHAT_OK;
72 }
73 if (!ctx->is_server)
74 return ASCIICHAT_OK;
75 result = crypto_handshake_server_send_parameters(ctx, transport);
76 if (result == ASCIICHAT_OK)
77 result = crypto_handshake_server_start(ctx, transport);
78 return result;
79 }
80 if (ctx->is_server) {
82 result = crypto_handshake_server_auth_challenge(ctx, transport, type, payload, length);
84 result = crypto_handshake_server_complete(ctx, transport, type, payload, length);
85 else
86 result = SET_ERRNO(ERROR_NETWORK_PROTOCOL, "Unexpected peer authentication state");
87 } else {
88 switch (type) {
90 if (security->parameters_received || ctx->state != CRYPTO_HANDSHAKE_INIT ||
91 length != sizeof(crypto_parameters_packet_t))
92 return SET_ERRNO(ERROR_NETWORK_PROTOCOL, "Invalid peer crypto parameters");
93 result = crypto_handshake_set_parameters(ctx, payload);
94 if (result == ASCIICHAT_OK && ctx->crypto_ctx.encrypt_data != !!ACIP_CRYPTO_HAS_ENCRYPT(security->mode))
95 return SET_ERRNO(ERROR_CRYPTO, "Peer cipher does not match negotiated policy");
96 security->parameters_received = result == ASCIICHAT_OK;
97 break;
99 if (!security->parameters_received)
100 return SET_ERRNO(ERROR_NETWORK_PROTOCOL, "Missing peer crypto parameters");
101 if (ctx->verify_server_key && length == ctx->crypto_ctx.public_key_size)
102 return SET_ERRNO(ERROR_CRYPTO_AUTH, "Peer omitted the required identity key");
103 result = crypto_handshake_client_key_exchange(ctx, transport, type, payload, length);
104 break;
106 result = crypto_handshake_client_auth_response(ctx, transport, type, payload, length);
107 break;
110 return SET_ERRNO(ERROR_CRYPTO_AUTH, "Peer skipped required mutual authentication");
111 result = crypto_handshake_client_complete(ctx, transport, type, payload, length);
112 break;
115 result = crypto_handshake_client_complete(ctx, transport, type, payload, length);
116 break;
117 default:
118 result = SET_ERRNO(ERROR_NETWORK_PROTOCOL, "Application packet before peer authentication");
119 }
120 }
121 if (result == ASCIICHAT_OK)
122 security->ready = ctx->state == CRYPTO_HANDSHAKE_READY;
123 else
125 if (result == ASCIICHAT_OK && security->ready)
126 result = acip_security_activate(transport);
127 return result;
128}
asciichat_error_t crypto_handshake_set_parameters(crypto_handshake_context_t *ctx, const crypto_parameters_packet_t *params)
Set crypto parameters from crypto_parameters_packet_t.
@ CRYPTO_HANDSHAKE_FAILED
@ CRYPTO_HANDSHAKE_AUTHENTICATING
@ CRYPTO_HANDSHAKE_INIT
@ CRYPTO_HANDSHAKE_DISABLED
@ CRYPTO_HANDSHAKE_KEY_EXCHANGE
@ CRYPTO_HANDSHAKE_READY
@ ERROR_INVALID_STATE
@ ERROR_NETWORK_PROTOCOL
Definition error_codes.h:76
@ ERROR_CRYPTO_AUTH
Definition error_codes.h:95
key_type_t type
Definition key_types.h:98
@ KEY_TYPE_ED25519
Definition key_types.h:54
#define ACIP_CRYPTO_NONE
No encryption, no authentication (plaintext only).
Definition packet.h:1138
#define ACIP_CRYPTO_HAS_AUTH(mode)
Check if crypto mode includes authentication.
Definition packet.h:1155
#define ACIP_CRYPTO_HAS_ENCRYPT(mode)
Check if crypto mode includes payload encryption.
Definition packet.h:1148
#define ACIP_CRYPTO_FULL
Full crypto: encryption + authentication.
Definition packet.h:1141
@ PACKET_TYPE_CRYPTO_HANDSHAKE_COMPLETE
Server -> Client: "encryption ready" (UNENCRYPTED).
Definition packet.h:338
@ PACKET_TYPE_CRYPTO_KEY_EXCHANGE_INIT
Server -> Client: {server_pubkey[32]} (UNENCRYPTED).
Definition packet.h:326
@ PACKET_TYPE_CRYPTO_AUTH_FAILED
Server -> Client: "authentication failed" (UNENCRYPTED).
Definition packet.h:334
@ PACKET_TYPE_CRYPTO_SERVER_AUTH_RESP
Server -> Client: {HMAC[32]} server proves knowledge (UNENCRYPTED).
Definition packet.h:336
@ PACKET_TYPE_PROTOCOL_VERSION
Protocol version and capabilities negotiation.
Definition packet.h:303
@ PACKET_TYPE_CRYPTO_AUTH_CHALLENGE
Server -> Client: {nonce[32]} (UNENCRYPTED).
Definition packet.h:330
@ PACKET_TYPE_CRYPTO_PARAMETERS
Server -> Client: Chosen algorithms + data sizes (UNENCRYPTED).
Definition packet.h:324
#define PROTOCOL_VERSION_MAJOR
Major protocol version number.
#define PROTOCOL_VERSION_MINOR
Minor protocol version number.
#define PROTOCOL_VERSION_PATCH
Patch protocol version number.
asciichat_error_t crypto_handshake_client_complete(crypto_handshake_context_t *ctx, acip_transport_t *transport, packet_type_t packet_type, const uint8_t *payload, size_t payload_len)
Client: Wait for handshake complete confirmation.
asciichat_error_t crypto_handshake_client_key_exchange(crypto_handshake_context_t *ctx, acip_transport_t *transport, packet_type_t packet_type, const uint8_t *payload, size_t payload_len)
Client: Process server's public key and send our public key.
asciichat_error_t crypto_handshake_client_auth_response(crypto_handshake_context_t *ctx, acip_transport_t *transport, packet_type_t packet_type, const uint8_t *payload, size_t payload_len)
Client: Process auth challenge and send response.
asciichat_error_t crypto_handshake_server_send_parameters(crypto_handshake_context_t *ctx, acip_transport_t *transport)
Server: Send CRYPTO_PARAMETERS and set handshake context sizes.
asciichat_error_t crypto_handshake_server_complete(crypto_handshake_context_t *ctx, acip_transport_t *transport, packet_type_t packet_type, const uint8_t *payload, size_t payload_len)
Server: Process auth response and complete handshake.
asciichat_error_t crypto_handshake_server_auth_challenge(crypto_handshake_context_t *ctx, acip_transport_t *transport, packet_type_t packet_type, const uint8_t *payload, size_t payload_len)
Server: Process client's public key and send auth challenge.
asciichat_error_t crypto_handshake_server_start(crypto_handshake_context_t *ctx, acip_transport_t *transport)
Server: Start crypto handshake by sending public key.
asciichat_error_t acip_security_activate(acip_transport_t *transport)
asciichat_error_t packet_send_via_transport(acip_transport_t *transport, packet_type_t type, const void *payload, size_t payload_len, uint32_t client_id)
Definition send.c:190
Cryptographic handshake context structure.
crypto_handshake_state_t state
Crypto parameters packet structure (Packet Type 15).
Definition packet.h:1037
Protocol version negotiation packet structure (Packet Type 1).
Definition packet.h:860
uint16_t protocol_patch
Patch protocol revision.
Definition packet.h:866
uint16_t protocol_revision
Minor protocol revision (server can be newer).
Definition packet.h:864
uint16_t protocol_version
Major protocol version (must match for compatibility).
Definition packet.h:862
uint8_t supports_encryption
Encryption & authentication mode bitmask (ACIP_CRYPTO_* constants: NONE, ENCRYPT, AUTH,...
Definition packet.h:868

References ACIP_CRYPTO_FULL, ACIP_CRYPTO_HAS_AUTH, ACIP_CRYPTO_HAS_ENCRYPT, ACIP_CRYPTO_NONE, acip_security_activate(), ASCIICHAT_OK, crypto_handshake_context_t::client_private_key, crypto_handshake_context_t::crypto_ctx, CRYPTO_HANDSHAKE_AUTHENTICATING, crypto_handshake_client_auth_response(), crypto_handshake_client_complete(), crypto_handshake_client_key_exchange(), CRYPTO_HANDSHAKE_DISABLED, CRYPTO_HANDSHAKE_FAILED, CRYPTO_HANDSHAKE_INIT, CRYPTO_HANDSHAKE_KEY_EXCHANGE, CRYPTO_HANDSHAKE_READY, crypto_handshake_server_auth_challenge(), crypto_handshake_server_complete(), crypto_handshake_server_send_parameters(), crypto_handshake_server_start(), crypto_handshake_set_parameters(), crypto_context_t::encrypt_data, ERROR_CRYPTO, ERROR_CRYPTO_AUTH, ERROR_INVALID_STATE, ERROR_NETWORK_PROTOCOL, acip_security::forbid_encryption, acip_security::handshake, crypto_handshake_context_t::has_password, crypto_handshake_context_t::is_server, KEY_TYPE_ED25519, acip_security::mode, NET_TO_HOST_U16, packet_send_via_transport(), PACKET_TYPE_CRYPTO_AUTH_CHALLENGE, PACKET_TYPE_CRYPTO_AUTH_FAILED, PACKET_TYPE_CRYPTO_HANDSHAKE_COMPLETE, PACKET_TYPE_CRYPTO_KEY_EXCHANGE_INIT, PACKET_TYPE_CRYPTO_PARAMETERS, PACKET_TYPE_CRYPTO_SERVER_AUTH_RESP, PACKET_TYPE_PROTOCOL_VERSION, acip_security::parameters_received, protocol_version_packet_t::protocol_patch, protocol_version_packet_t::protocol_revision, protocol_version_packet_t::protocol_version, PROTOCOL_VERSION_MAJOR, PROTOCOL_VERSION_MINOR, PROTOCOL_VERSION_PATCH, crypto_context_t::public_key_size, acip_security::ready, crypto_handshake_context_t::require_client_auth, acip_security::require_encryption, SET_ERRNO, crypto_handshake_context_t::state, protocol_version_packet_t::supports_encryption, private_key_t::type, crypto_handshake_context_t::verify_server_key, and acip_security::version_received.

Referenced by peer_crypto_receive().

◆ acip_security_rekey_encode()

asciichat_error_t acip_security_rekey_encode ( unsigned flow,
crypto_rekey_message_t type,
const void * payload,
size_t length,
void * packet,
size_t capacity,
size_t * written )

Definition at line 149 of file lib/network/acip/security.c.

150 {
151 if (type <= CRYPTO_REKEY_NONE || type > CRYPTO_REKEY_NEEDED || flow >= CRYPTO_RECORD_CHANNELS)
152 return SET_ERRNO(ERROR_INVALID_PARAM, "Invalid rekey message");
153 return packet_encode(rekey_types[type], payload, length, flow, packet, capacity, written);
154}
asciichat_error_t packet_encode(packet_type_t type, const void *payload, size_t length, uint32_t client_id, void *output, size_t capacity, size_t *written)
Definition packet.c:67
#define CRYPTO_RECORD_CHANNELS
Definition record.h:7
@ CRYPTO_REKEY_NEEDED
Definition rekey.h:13

References CRYPTO_RECORD_CHANNELS, CRYPTO_REKEY_NEEDED, ERROR_INVALID_PARAM, packet_encode(), and SET_ERRNO.

Referenced by acip_security_rekey_seal().

◆ acip_security_rekey_packet()

bool acip_security_rekey_packet ( uint16_t type)

Definition at line 145 of file lib/network/acip/security.c.

145 {
146 return rekey_message(type) != CRYPTO_REKEY_NONE;
147}
@ CRYPTO_REKEY_NONE
Definition rekey.h:7

References CRYPTO_REKEY_NONE.

Referenced by quic_connection_submit().

◆ acip_security_rekey_receive()

asciichat_error_t acip_security_rekey_receive ( crypto_rekey_session_t * session,
acip_traffic_class_t flow,
acip_delivery_t delivery,
const void * packet,
size_t length,
uint64_t now,
bool * consumed )

Definition at line 156 of file lib/network/acip/security.c.

158 {
159 packet_header_t header;
160 asciichat_error_t result = packet_validate(packet, length, 0, &header);
161 if (result != ASCIICHAT_OK)
162 return result;
163 return crypto_rekey_session_receive(session, flow, delivery, rekey_message(NET_TO_HOST_U16(header.type)),
164 (const uint8_t *)packet + sizeof(header), length - sizeof(header), now, consumed);
165}
asciichat_error_t crypto_rekey_session_receive(crypto_rekey_session_t *s, unsigned flow, unsigned delivery, crypto_rekey_message_t type, const void *payload, size_t bytes, uint64_t now, bool *consumed)
Definition rekey.c:127

References ASCIICHAT_OK, crypto_rekey_session_receive(), NET_TO_HOST_U16, and packet_validate().

◆ acip_security_rekey_seal()

asciichat_error_t acip_security_rekey_seal ( crypto_record_t * records,
unsigned flow,
crypto_rekey_message_t message,
const void * payload,
size_t length,
uint8_t ** wire,
size_t * written )

Definition at line 167 of file lib/network/acip/security.c.

168 {
170 size_t packet_length = 0;
171 asciichat_error_t result =
172 acip_security_rekey_encode(flow, message, payload, length, packet, sizeof(packet), &packet_length);
173 return result == ASCIICHAT_OK ? acip_packet_seal(records, (acip_traffic_class_t)flow, ACIP_DELIVERY_RELIABLE, packet,
174 packet_length, wire, written)
175 : result;
176}
asciichat_error_t acip_security_rekey_encode(unsigned flow, crypto_rekey_message_t type, const void *payload, size_t length, void *packet, size_t capacity, size_t *written)
asciichat_error_t acip_packet_seal(crypto_record_t *records, acip_traffic_class_t flow, acip_delivery_t delivery, const void *packet, size_t length, uint8_t **output, size_t *written)
Definition prepare.c:125
#define CRYPTO_PUBLIC_KEY_SIZE
Public key size (X25519).
Definition sizes.h:67

References ACIP_DELIVERY_RELIABLE, acip_packet_seal(), acip_security_rekey_encode(), ASCIICHAT_OK, and CRYPTO_PUBLIC_KEY_SIZE.

Referenced by acip_security_next_control().

◆ acip_security_request_rekey()

asciichat_error_t acip_security_request_rekey ( acip_transport_t * transport)

Definition at line 273 of file lib/network/acip/security.c.

273 {
274 if (!transport || !transport->crypto_ctx || !transport->crypto_ctx->encrypt_data)
275 return SET_ERRNO(ERROR_INVALID_STATE, "An encrypted authenticated session is required for rotation");
276 crypto_session_t *session = NULL;
277 asciichat_error_t result = crypto_session_lock(transport->crypto_ctx, &session);
278 if (result == ASCIICHAT_OK) {
279 result = crypto_rekey_session_request(&session->rotation, time_get_ns());
280 crypto_session_unlock(session);
281 }
282 return result;
283}
asciichat_error_t crypto_rekey_session_request(crypto_rekey_session_t *s, uint64_t now)
Definition rekey.c:118
crypto_rekey_session_t rotation

References ASCIICHAT_OK, acip_transport::crypto_ctx, crypto_rekey_session_request(), crypto_session_lock(), crypto_session_unlock(), crypto_context_t::encrypt_data, ERROR_INVALID_STATE, crypto_session::rotation, and SET_ERRNO.

◆ acip_security_seal()

asciichat_error_t acip_security_seal ( crypto_context_t * crypto,
acip_traffic_class_t flow,
acip_delivery_t delivery,
const void * packet,
size_t length,
uint8_t ** output,
size_t * written )

Definition at line 285 of file lib/network/acip/security.c.

286 {
287 crypto_session_t *session = NULL;
288 asciichat_error_t result = crypto_session_lock(crypto, &session);
289 if (result == ASCIICHAT_OK) {
290 result = acip_packet_seal(&session->records, flow, delivery, packet, length, output, written);
291 crypto_session_unlock(session);
292 }
293 return result;
294}

References acip_packet_seal(), ASCIICHAT_OK, crypto_session_lock(), crypto_session_unlock(), and crypto_session::records.

Referenced by browser_security_packet(), client_encrypt_packet(), quic_connection_submit(), and quic_connection_submit_datagram().

◆ acip_security_start()

asciichat_error_t acip_security_start ( acip_security_t * security,
acip_transport_t * transport )

Definition at line 18 of file lib/network/acip/security.c.

18 {
19 if (!security || !transport || security->mode > ACIP_CRYPTO_FULL ||
21 return SET_ERRNO(ERROR_INVALID_STATE, "Invalid peer security initialization");
22 security->handshake.addressless_transport = true;
23 transport->crypto_ctx = &security->handshake.crypto_ctx;
25 if (security->handshake.is_server)
26 return ASCIICHAT_OK;
28 protocol_version_packet_init(&version, security->mode);
29 return packet_send_via_transport(transport, PACKET_TYPE_PROTOCOL_VERSION, &version, sizeof(version), 0);
30}
void protocol_version_packet_init(protocol_version_packet_t *version, uint8_t supports_encryption)
Initialize a protocol version packet with the current wire version.
Definition packet.c:37

References ACIP_CRYPTO_FULL, ACIP_CRYPTO_HAS_ENCRYPT, crypto_handshake_context_t::addressless_transport, ASCIICHAT_OK, acip_transport::crypto_ctx, crypto_handshake_context_t::crypto_ctx, CRYPTO_HANDSHAKE_INIT, crypto_context_t::encrypt_data, ERROR_INVALID_STATE, acip_security::handshake, crypto_handshake_context_t::is_server, acip_security::mode, packet_send_via_transport(), PACKET_TYPE_PROTOCOL_VERSION, protocol_version_packet_init(), SET_ERRNO, and crypto_handshake_context_t::state.

Referenced by peer_crypto_create().