Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,23 @@ if meson.is_cross_build()
compiler = meson.get_compiler('c', native : false)
endif

has_explicit_bzero = compiler.has_function(
'explicit_bzero',
prefix: '#define _DEFAULT_SOURCE\n#include <string.h>',
args: ['-D_DEFAULT_SOURCE'],
)

has_pqc = compiler.links('''
#include <jose/jose.h>
int main(void) {
json_auto_t *j = json_pack("{s:s}", "alg", "ML-KEM-768");
if (!jose_jwk_gen(NULL, j))
return 1;
json_auto_t *enc = jose_jwk_kem_enc(NULL, j);
return enc ? 0 : 1;
}
''', dependencies: jose, name: 'ML-KEM KEM API support in jose')

message(compiler.version())
message(compiler.get_id())

Expand Down
43 changes: 35 additions & 8 deletions src/keys.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,9 @@ free_tang_keys_info(struct tang_keys_info* tki)
}

json_t* to_free[] = {tki->m_keys, tki->m_rotated_keys,
tki->m_payload, tki->m_sign
tki->m_payload,
tki->m_kem_payload,
tki->m_sign
};
size_t len = sizeof(to_free) / sizeof(to_free[0]);

Expand Down Expand Up @@ -164,10 +166,11 @@ new_tang_keys_info(void)
tki->m_keys = json_array();
tki->m_rotated_keys = json_array();
tki->m_payload = json_array();
tki->m_kem_payload = json_array();
tki->m_sign = json_array();

if (!tki->m_keys || !tki->m_rotated_keys ||
!tki->m_payload || !tki->m_sign) {
!tki->m_payload || !tki->m_kem_payload || !tki->m_sign) {
free_tang_keys_info(tki);
return NULL;
}
Expand Down Expand Up @@ -220,7 +223,7 @@ cleanup_str(char** str)
*str = NULL;
}

static json_t*
json_t*
jwk_sign(const json_t* to_sign, const json_t* sig_keys)
{
if (!sig_keys || !json_is_array(sig_keys) || !json_is_array(to_sign)) {
Expand Down Expand Up @@ -291,8 +294,12 @@ prepare_payload_and_sign(struct tang_keys_info* tki)
continue;
}
} else if (jwk_valid_for_deriving_keys(jwk)) {
if (json_array_append(tki->m_payload, jwk) == -1) {
continue;
const char* kty = json_string_value(
json_object_get(jwk, "kty"));
if (kty && strcmp(kty, "AKP") == 0) {
json_array_append(tki->m_kem_payload, jwk);
} else {
json_array_append(tki->m_payload, jwk);
}
}
}
Expand All @@ -302,17 +309,32 @@ prepare_payload_and_sign(struct tang_keys_info* tki)
return 1;
}

struct key_spec {
const char* alg;
int optional;
};

static int
create_new_keys(const char* jwkdir)
{
const char* alg[] = {"ES512", "ECMR", NULL};
const struct key_spec specs[] = {
{"ES512", 0},
{"ECMR", 0},
{"ML-KEM-768", 1},
{NULL, 0}
};
char path[PATH_MAX];

/* Set default umask for file creation. */
umask(0337);
for (int i = 0; alg[i] != NULL; i++) {
json_auto_t* jwk = jwk_generate(alg[i]);
for (int i = 0; specs[i].alg != NULL; i++) {
json_auto_t* jwk = jwk_generate(specs[i].alg);
if (!jwk) {
if (specs[i].optional) {
fprintf(stderr, "Skipping optional key %s (not supported)\n",
specs[i].alg);
continue;
}
return 0;
}
__attribute__ ((__cleanup__(cleanup_str))) char* thp = jwk_thumbprint(jwk, DEFAULT_THP_HASH);
Expand Down Expand Up @@ -387,6 +409,11 @@ load_keys(const char* jwkdir)
tki->m_rotated_keys_count++;
} else {
tki->m_keys_count++;
const char* kty = json_string_value(
json_object_get(json, "kty"));
if (kty && strcmp(kty, "AKP") == 0) {
tki->m_has_pqc = 1;
}
}

if (json_array_append(arr, json) == -1) {
Expand Down
11 changes: 9 additions & 2 deletions src/keys.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,26 @@ struct tang_keys_info {
json_t* m_keys; /* Regular keys. */
json_t* m_rotated_keys; /* Rotated keys. */

json_t* m_payload; /* Payload made of regular keys capable of
json_t* m_payload; /* Payload made of regular EC keys capable of
* either signing+verifying or deriving new
* keys. */
* keys (excludes KEM keys). */

json_t* m_kem_payload; /* Payload made of KEM keys (kty=AKP) for
* the /adv-kem endpoint. */

json_t* m_sign; /* Set of signing keys made from regular
keys. */

size_t m_keys_count; /* Number of regular keys. */
size_t m_rotated_keys_count; /* Number of rotated keys. */

int m_has_pqc; /* Non-zero if a PQC key (e.g. ML-KEM) is
available among regular keys. */
};

void cleanup_tang_keys_info(struct tang_keys_info**);
void free_tang_keys_info(struct tang_keys_info*);
struct tang_keys_info* read_keys(const char* /* jwkdir */);
json_t* jwk_sign(const json_t* /* to_sign */, const json_t* /* sig_keys */);
json_t* find_jws(struct tang_keys_info* /* tki */, const char* /* thp */);
json_t* find_jwk(struct tang_keys_info* /* tki */, const char* /* thp */);
8 changes: 8 additions & 0 deletions src/meson.build
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
pqc_source = has_pqc ? 'pqc.c' : 'pqc_noop.c'
pqc_args = []
if has_explicit_bzero
pqc_args += ['-DHAVE_EXPLICIT_BZERO']
endif

tangd = executable('tangd',
'http.c',
'keys.c',
'tangd.c',
'socket.c',
pqc_source,
c_args: pqc_args,
dependencies: [jose, http_parser],
install: true,
install_dir: libexecdir
Expand Down
Loading
Loading