summaryrefslogtreecommitdiff
path: root/ssh-sk.c
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2019-12-30 09:20:36 +0000
committerDamien Miller <djm@mindrot.org>2019-12-30 20:57:59 +1100
commit2fe05fcb4a2695f190b4fcf27770b655586ab349 (patch)
treec595b453a5cab52965efa277b9e841b562f0e015 /ssh-sk.c
parent4532bd01d57ee13c3ca881eceac1bf9da96a4d7e (diff)
upstream: Factor out parsing of struct sk_enroll_response
We'll reuse this for extracting resident keys from a device. feedback and ok markus@ OpenBSD-Commit-ID: 9bc1efd9c6897eac4df0983746cf6578c1542273
Diffstat (limited to 'ssh-sk.c')
-rw-r--r--ssh-sk.c101
1 files changed, 64 insertions, 37 deletions
diff --git a/ssh-sk.c b/ssh-sk.c
index 9e5637353..01927669e 100644
--- a/ssh-sk.c
+++ b/ssh-sk.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-sk.c,v 1.18 2019/12/13 19:09:10 djm Exp $ */ 1/* $OpenBSD: ssh-sk.c,v 1.19 2019/12/30 09:20:36 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2019 Google LLC 3 * Copyright (c) 2019 Google LLC
4 * 4 *
@@ -254,6 +254,65 @@ sshsk_ed25519_assemble(struct sk_enroll_response *resp, struct sshkey **keyp)
254 return r; 254 return r;
255} 255}
256 256
257static int
258sshsk_key_from_response(int alg, const char *application, uint8_t flags,
259 struct sk_enroll_response *resp, struct sshkey **keyp)
260{
261 struct sshkey *key = NULL;
262 int r = SSH_ERR_INTERNAL_ERROR;
263
264 *keyp = NULL;
265
266 /* Check response validity */
267 if (resp->public_key == NULL || resp->key_handle == NULL ||
268 resp->signature == NULL ||
269 (resp->attestation_cert == NULL && resp->attestation_cert_len != 0)) {
270 error("%s: sk_enroll response invalid", __func__);
271 r = SSH_ERR_INVALID_FORMAT;
272 goto out;
273 }
274 switch (alg) {
275#ifdef WITH_OPENSSL
276 case SSH_SK_ECDSA:
277 if ((r = sshsk_ecdsa_assemble(resp, &key)) != 0)
278 goto out;
279 break;
280#endif /* WITH_OPENSSL */
281 case SSH_SK_ED25519:
282 if ((r = sshsk_ed25519_assemble(resp, &key)) != 0)
283 goto out;
284 break;
285 default:
286 error("%s: unsupported algorithm %d", __func__, alg);
287 r = SSH_ERR_INVALID_ARGUMENT;
288 goto out;
289 }
290 key->sk_flags = flags;
291 if ((key->sk_key_handle = sshbuf_new()) == NULL ||
292 (key->sk_reserved = sshbuf_new()) == NULL) {
293 error("%s: allocation failed", __func__);
294 r = SSH_ERR_ALLOC_FAIL;
295 goto out;
296 }
297 if ((key->sk_application = strdup(application)) == NULL) {
298 error("%s: strdup application failed", __func__);
299 r = SSH_ERR_ALLOC_FAIL;
300 goto out;
301 }
302 if ((r = sshbuf_put(key->sk_key_handle, resp->key_handle,
303 resp->key_handle_len)) != 0) {
304 error("%s: buffer error: %s", __func__, ssh_err(r));
305 goto out;
306 }
307 /* success */
308 r = 0;
309 *keyp = key;
310 key = NULL;
311 out:
312 sshkey_free(key);
313 return r;
314}
315
257int 316int
258sshsk_enroll(int type, const char *provider_path, const char *application, 317sshsk_enroll(int type, const char *provider_path, const char *application,
259 uint8_t flags, struct sshbuf *challenge_buf, struct sshkey **keyp, 318 uint8_t flags, struct sshbuf *challenge_buf, struct sshkey **keyp,
@@ -327,43 +386,11 @@ sshsk_enroll(int type, const char *provider_path, const char *application,
327 r = SSH_ERR_INVALID_FORMAT; /* XXX error codes in API? */ 386 r = SSH_ERR_INVALID_FORMAT; /* XXX error codes in API? */
328 goto out; 387 goto out;
329 } 388 }
330 /* Check response validity */ 389
331 if (resp->public_key == NULL || resp->key_handle == NULL || 390 if ((r = sshsk_key_from_response(alg, application, flags,
332 resp->signature == NULL || 391 resp, &key)) != 0)
333 (resp->attestation_cert == NULL && resp->attestation_cert_len != 0)) {
334 error("%s: sk_enroll response invalid", __func__);
335 r = SSH_ERR_INVALID_FORMAT;
336 goto out;
337 }
338 switch (type) {
339#ifdef WITH_OPENSSL
340 case KEY_ECDSA_SK:
341 if ((r = sshsk_ecdsa_assemble(resp, &key)) != 0)
342 goto out;
343 break;
344#endif /* WITH_OPENSSL */
345 case KEY_ED25519_SK:
346 if ((r = sshsk_ed25519_assemble(resp, &key)) != 0)
347 goto out;
348 break;
349 }
350 key->sk_flags = flags;
351 if ((key->sk_key_handle = sshbuf_new()) == NULL ||
352 (key->sk_reserved = sshbuf_new()) == NULL) {
353 error("%s: allocation failed", __func__);
354 r = SSH_ERR_ALLOC_FAIL;
355 goto out;
356 }
357 if ((key->sk_application = strdup(application)) == NULL) {
358 error("%s: strdup application failed", __func__);
359 r = SSH_ERR_ALLOC_FAIL;
360 goto out;
361 }
362 if ((r = sshbuf_put(key->sk_key_handle, resp->key_handle,
363 resp->key_handle_len)) != 0) {
364 error("%s: buffer error: %s", __func__, ssh_err(r));
365 goto out; 392 goto out;
366 } 393
367 /* Optionally fill in the attestation information */ 394 /* Optionally fill in the attestation information */
368 if (attest != NULL) { 395 if (attest != NULL) {
369 if ((r = sshbuf_put_cstring(attest, "sk-attest-v00")) != 0 || 396 if ((r = sshbuf_put_cstring(attest, "sk-attest-v00")) != 0 ||