=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/ssh/ssh-sk-client.c,v retrieving revision 1.9 retrieving revision 1.10 diff -u -r1.9 -r1.10 --- src/usr.bin/ssh/ssh-sk-client.c 2021/04/03 06:18:41 1.9 +++ src/usr.bin/ssh/ssh-sk-client.c 2021/10/28 02:54:18 1.10 @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-sk-client.c,v 1.9 2021/04/03 06:18:41 djm Exp $ */ +/* $OpenBSD: ssh-sk-client.c,v 1.10 2021/10/28 02:54:18 djm Exp $ */ /* * Copyright (c) 2019 Google LLC * @@ -365,17 +365,44 @@ return r; } +static void +sshsk_free_resident_key(struct sshsk_resident_key *srk) +{ + if (srk == NULL) + return; + sshkey_free(srk->key); + freezero(srk->user_id, srk->user_id_len); + free(srk); +} + + +void +sshsk_free_resident_keys(struct sshsk_resident_key **srks, size_t nsrks) +{ + size_t i; + + if (srks == NULL || nsrks == 0) + return; + + for (i = 0; i < nsrks; i++) + sshsk_free_resident_key(srks[i]); + free(srks); +} + int sshsk_load_resident(const char *provider_path, const char *device, - const char *pin, struct sshkey ***keysp, size_t *nkeysp) + const char *pin, u_int flags, struct sshsk_resident_key ***srksp, + size_t *nsrksp) { int oerrno, r = SSH_ERR_INTERNAL_ERROR; struct sshbuf *kbuf = NULL, *req = NULL, *resp = NULL; - struct sshkey *key = NULL, **keys = NULL, **tmp; - size_t i, nkeys = 0; + struct sshkey *key = NULL; + struct sshsk_resident_key *srk = NULL, **srks = NULL, **tmp; + u_char *userid = NULL; + size_t userid_len = 0, nsrks = 0; - *keysp = NULL; - *nkeysp = 0; + *srksp = NULL; + *nsrksp = 0; if ((resp = sshbuf_new()) == NULL || (kbuf = sshbuf_new()) == NULL || @@ -386,7 +413,8 @@ if ((r = sshbuf_put_cstring(req, provider_path)) != 0 || (r = sshbuf_put_cstring(req, device)) != 0 || - (r = sshbuf_put_cstring(req, pin)) != 0) { + (r = sshbuf_put_cstring(req, pin)) != 0 || + (r = sshbuf_put_u32(req, flags)) != 0) { error_fr(r, "compose"); goto out; } @@ -395,10 +423,11 @@ goto out; while (sshbuf_len(resp) != 0) { - /* key, comment */ + /* key, comment, user_id */ if ((r = sshbuf_get_stringb(resp, kbuf)) != 0 || - (r = sshbuf_get_cstring(resp, NULL, NULL)) != 0) { - error_fr(r, "parse signature"); + (r = sshbuf_get_cstring(resp, NULL, NULL)) != 0 || + (r = sshbuf_get_string(resp, &userid, &userid_len)) != 0) { + error_fr(r, "parse"); r = SSH_ERR_INVALID_FORMAT; goto out; } @@ -406,29 +435,40 @@ error_fr(r, "decode key"); goto out; } - if ((tmp = recallocarray(keys, nkeys, nkeys + 1, - sizeof(*keys))) == NULL) { - error_f("recallocarray keys failed"); + if ((srk = calloc(1, sizeof(*srk))) == NULL) { + error_f("calloc failed"); goto out; } - debug_f("keys[%zu]: %s %s", nkeys, sshkey_type(key), - key->sk_application); - keys = tmp; - keys[nkeys++] = key; + srk->key = key; key = NULL; + srk->user_id = userid; + srk->user_id_len = userid_len; + userid = NULL; + userid_len = 0; + if ((tmp = recallocarray(srks, nsrks, nsrks + 1, + sizeof(*srks))) == NULL) { + error_f("recallocarray keys failed"); + goto out; + } + debug_f("srks[%zu]: %s %s uidlen %zu", nsrks, + sshkey_type(srk->key), srk->key->sk_application, + srk->user_id_len); + srks = tmp; + srks[nsrks++] = srk; + srk = NULL; } /* success */ r = 0; - *keysp = keys; - *nkeysp = nkeys; - keys = NULL; - nkeys = 0; + *srksp = srks; + *nsrksp = nsrks; + srks = NULL; + nsrks = 0; out: oerrno = errno; - for (i = 0; i < nkeys; i++) - sshkey_free(keys[i]); - free(keys); + sshsk_free_resident_key(srk); + sshsk_free_resident_keys(srks, nsrks); + freezero(userid, userid_len); sshkey_free(key); sshbuf_free(kbuf); sshbuf_free(req);