Skip to content

Commit

Permalink
split out keymgmgt
Browse files Browse the repository at this point in the history
closer for the big refactor of directory-server left:

* make sure no descriptor leaks from parent
* re-add state management
* re-add debug push

then we can add the fancy features all this was for.
  • Loading branch information
letoram committed Sep 24, 2023
1 parent 2d78f3f commit 58bd068
Show file tree
Hide file tree
Showing 12 changed files with 431 additions and 142 deletions.
22 changes: 17 additions & 5 deletions src/a12/a12.c
Expand Up @@ -1300,6 +1300,13 @@ static struct blob_out** alloc_attach_blob(struct a12_state* S)
return parent;
}

void a12_set_session(
struct pk_response* dst, uint8_t pubk[static 32], uint8_t privk[static 32])
{
x25519_public_key(privk, dst->key_pub);
x25519_shared_secret(dst->key_session, privk, pubk);
}

/*
* Simplified form of enqueue bstream below, we already have the buffer
* in memory so just build a different blob-out node with a copy
Expand Down Expand Up @@ -1487,8 +1494,12 @@ static bool authdec_buffer(const char* src, struct a12_state* S, size_t block_sz
static void hello_auth_server_hello(struct a12_state* S)
{
uint8_t pubk[32];
uint8_t remote_pubk[32];

uint8_t nonce[8];
int cfl = S->decode[20];

memcpy(remote_pubk, &S->decode[21], 32);
a12int_trace(A12_TRACE_CRYPTO, "state=complete:method=%d", cfl);

/* here is a spot for having more authentication modes if needed (version bump) */
Expand All @@ -1510,7 +1521,7 @@ static void hello_auth_server_hello(struct a12_state* S)
arcan_random(nonce, 8);
send_hello_packet(S, HELLO_MODE_EPHEMPK, pubk, nonce);

x25519_shared_secret((uint8_t*)S->opts->secret, ek, &S->decode[21]);
x25519_shared_secret((uint8_t*)S->opts->secret, ek, remote_pubk);
trace_crypto_key(S->server, "ephem_pub", pubk, 32);
update_keymaterial(S, S->opts->secret, 32, nonce);
S->authentic = AUTH_EPHEMERAL_PK;
Expand All @@ -1527,25 +1538,26 @@ static void hello_auth_server_hello(struct a12_state* S)

/* the lookup function returns the key that should be used in the reply
* and to calculate the shared secret */
trace_crypto_key(S->server, "state=client_pk", &S->decode[21], 32);
struct pk_response res = S->opts->pk_lookup(&S->decode[21]);
trace_crypto_key(S->server, "state=client_pk", remote_pubk, 32);
struct pk_response res = S->opts->pk_lookup(remote_pubk);
if (!res.authentic){
a12int_trace(A12_TRACE_CRYPTO, "state=eperm:kind=x25519-pk-fail");
fail_state(S);
return;
}

memcpy((uint8_t*)S->opts->secret, res.key_session, 32);
memcpy(pubk, res.key_pub, 32);

/* hello packet here will still use the keystate from the process_srvfirst
* which will use the client provided nonce, KDF on preshare-pw */
x25519_public_key(res.key, pubk);
arcan_random(nonce, 8);
send_hello_packet(S, HELLO_MODE_REALPK, pubk, nonce);
memcpy(S->keys.remote_pub, &S->decode[21], 32);
trace_crypto_key(S->server, "state=client_pk_ok:respond_pk", pubk, 32);

/* now we can switch keys, note that the new nonce applies for both enc and dec
* states regardless of the nonce the client provided in the first message */
x25519_shared_secret((uint8_t*)S->opts->secret, res.key, &S->decode[21]);
trace_crypto_key(S->server, "state=server_ssecret", (uint8_t*)S->opts->secret, 32);
update_keymaterial(S, S->opts->secret, 32, nonce);

Expand Down
20 changes: 15 additions & 5 deletions src/a12/a12.h
Expand Up @@ -42,14 +42,14 @@ struct a12_state;
* and client- side or the communication will fail regardless of key validity.
*
* return the private key to use with the public key received (server only)
* OR (migration to better process- separation friendly interface), got_session
* set and key_pub + derived session will be provided rather than the key_priv.
*/
struct pk_response {
bool authentic;

/* For server-side, reply with the key that should be used with the specific
* client if there is differentiation, for client-side, the private key in the
* structure to a12_client will be used */
uint8_t key[32];
uint8_t key_pub[32];
uint8_t key_session[32];

/* If state store is provided / permitted for the key, return a lookup function
* for creating or reading named resources from it */
Expand All @@ -60,7 +60,9 @@ struct pk_response {
struct a12_context_options {
/* Provide to enable asymetric key authentication, set valid in the return to
* allow the key, otherwise the session may be continued for a random number of
* time or bytes before being terminated. */
* time or bytes before being terminated. If want_session is requested, the
* lookup function, if it is able to (legacy) should set got_session in the
* reply and calculate the x25519v shared secret itself. */
struct pk_response (*pk_lookup)(uint8_t pub[static 32]);

/* Client only, provide the private key to use with the connection. All [0]
Expand Down Expand Up @@ -127,6 +129,14 @@ struct a12_state* a12_server(struct a12_context_options*);
bool
a12_free(struct a12_state*);

/*
* Used by the canonical key lookup function that provides the pk_response.
* Provide the remote public key in pubk, and the local private key in privk.
* Calculate the session key and local public key and set in [dst].
*/
void a12_set_session(
struct pk_response* dst, uint8_t pubk[static 32], uint8_t privk[static 32]);

/*
* Take an incoming byte buffer and append to the current state of
* the channel. Any received events will be pushed via the callback.
Expand Down

0 comments on commit 58bd068

Please sign in to comment.