summaryrefslogtreecommitdiff
path: root/sshkey.c
diff options
context:
space:
mode:
authormarkus@openbsd.org <markus@openbsd.org>2019-11-12 19:33:08 +0000
committerDamien Miller <djm@mindrot.org>2019-11-13 08:54:09 +1100
commit2c55744a56de0ffc81fe445a1e7fc5cd308712b3 (patch)
tree349cdc436823354aca60031358a6030313b6002d /sshkey.c
parentfd1a3b5e38721b1d69aae2d9de1a1d9155dfa5c7 (diff)
upstream: enable ed25519 support; ok djm
OpenBSD-Commit-ID: 1a399c5b3ef15bd8efb916110cf5a9e0b554ab7e
Diffstat (limited to 'sshkey.c')
-rw-r--r--sshkey.c154
1 files changed, 153 insertions, 1 deletions
diff --git a/sshkey.c b/sshkey.c
index 269f37b39..1b66d4ec7 100644
--- a/sshkey.c
+++ b/sshkey.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshkey.c,v 1.89 2019/11/12 19:31:18 markus Exp $ */ 1/* $OpenBSD: sshkey.c,v 1.90 2019/11/12 19:33:08 markus Exp $ */
2/* 2/*
3 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
4 * Copyright (c) 2008 Alexander von Gernler. All rights reserved. 4 * Copyright (c) 2008 Alexander von Gernler. All rights reserved.
@@ -107,6 +107,10 @@ static const struct keytype keytypes[] = {
107 { "ssh-ed25519", "ED25519", NULL, KEY_ED25519, 0, 0, 0 }, 107 { "ssh-ed25519", "ED25519", NULL, KEY_ED25519, 0, 0, 0 },
108 { "ssh-ed25519-cert-v01@openssh.com", "ED25519-CERT", NULL, 108 { "ssh-ed25519-cert-v01@openssh.com", "ED25519-CERT", NULL,
109 KEY_ED25519_CERT, 0, 1, 0 }, 109 KEY_ED25519_CERT, 0, 1, 0 },
110 { "sk-ssh-ed25519@openssh.com", "ED25519-SK", NULL,
111 KEY_ED25519_SK, 0, 0, 0 },
112 { "sk-ssh-ed25519-cert-v01@openssh.com", "ED25519-SK-CERT", NULL,
113 KEY_ED25519_SK_CERT, 0, 1, 0 },
110#ifdef WITH_XMSS 114#ifdef WITH_XMSS
111 { "ssh-xmss@openssh.com", "XMSS", NULL, KEY_XMSS, 0, 0, 0 }, 115 { "ssh-xmss@openssh.com", "XMSS", NULL, KEY_XMSS, 0, 0, 0 },
112 { "ssh-xmss-cert-v01@openssh.com", "XMSS-CERT", NULL, 116 { "ssh-xmss-cert-v01@openssh.com", "XMSS-CERT", NULL,
@@ -337,6 +341,8 @@ sshkey_size(const struct sshkey *k)
337#endif /* WITH_OPENSSL */ 341#endif /* WITH_OPENSSL */
338 case KEY_ED25519: 342 case KEY_ED25519:
339 case KEY_ED25519_CERT: 343 case KEY_ED25519_CERT:
344 case KEY_ED25519_SK:
345 case KEY_ED25519_SK_CERT:
340 case KEY_XMSS: 346 case KEY_XMSS:
341 case KEY_XMSS_CERT: 347 case KEY_XMSS_CERT:
342 return 256; /* XXX */ 348 return 256; /* XXX */
@@ -353,6 +359,7 @@ sshkey_type_is_valid_ca(int type)
353 case KEY_ECDSA: 359 case KEY_ECDSA:
354 case KEY_ECDSA_SK: 360 case KEY_ECDSA_SK:
355 case KEY_ED25519: 361 case KEY_ED25519:
362 case KEY_ED25519_SK:
356 case KEY_XMSS: 363 case KEY_XMSS:
357 return 1; 364 return 1;
358 default: 365 default:
@@ -368,6 +375,20 @@ sshkey_is_cert(const struct sshkey *k)
368 return sshkey_type_is_cert(k->type); 375 return sshkey_type_is_cert(k->type);
369} 376}
370 377
378int
379sshkey_is_sk(const struct sshkey *k)
380{
381 if (k == NULL)
382 return 0;
383 switch (sshkey_type_plain(k->type)) {
384 case KEY_ECDSA_SK:
385 case KEY_ED25519_SK:
386 return 1;
387 default:
388 return 0;
389 }
390}
391
371/* Return the cert-less equivalent to a certified key type */ 392/* Return the cert-less equivalent to a certified key type */
372int 393int
373sshkey_type_plain(int type) 394sshkey_type_plain(int type)
@@ -383,6 +404,8 @@ sshkey_type_plain(int type)
383 return KEY_ECDSA_SK; 404 return KEY_ECDSA_SK;
384 case KEY_ED25519_CERT: 405 case KEY_ED25519_CERT:
385 return KEY_ED25519; 406 return KEY_ED25519;
407 case KEY_ED25519_SK_CERT:
408 return KEY_ED25519_SK;
386 case KEY_XMSS_CERT: 409 case KEY_XMSS_CERT:
387 return KEY_XMSS; 410 return KEY_XMSS;
388 default: 411 default:
@@ -563,6 +586,8 @@ sshkey_new(int type)
563#endif /* WITH_OPENSSL */ 586#endif /* WITH_OPENSSL */
564 case KEY_ED25519: 587 case KEY_ED25519:
565 case KEY_ED25519_CERT: 588 case KEY_ED25519_CERT:
589 case KEY_ED25519_SK:
590 case KEY_ED25519_SK_CERT:
566 case KEY_XMSS: 591 case KEY_XMSS:
567 case KEY_XMSS_CERT: 592 case KEY_XMSS_CERT:
568 /* no need to prealloc */ 593 /* no need to prealloc */
@@ -615,6 +640,12 @@ sshkey_free(struct sshkey *k)
615 break; 640 break;
616# endif /* OPENSSL_HAS_ECC */ 641# endif /* OPENSSL_HAS_ECC */
617#endif /* WITH_OPENSSL */ 642#endif /* WITH_OPENSSL */
643 case KEY_ED25519_SK:
644 case KEY_ED25519_SK_CERT:
645 free(k->sk_application);
646 sshbuf_free(k->sk_key_handle);
647 sshbuf_free(k->sk_reserved);
648 /* FALLTHROUGH */
618 case KEY_ED25519: 649 case KEY_ED25519:
619 case KEY_ED25519_CERT: 650 case KEY_ED25519_CERT:
620 freezero(k->ed25519_pk, ED25519_PK_SZ); 651 freezero(k->ed25519_pk, ED25519_PK_SZ);
@@ -734,6 +765,13 @@ sshkey_equal_public(const struct sshkey *a, const struct sshkey *b)
734 return 1; 765 return 1;
735# endif /* OPENSSL_HAS_ECC */ 766# endif /* OPENSSL_HAS_ECC */
736#endif /* WITH_OPENSSL */ 767#endif /* WITH_OPENSSL */
768 case KEY_ED25519_SK:
769 case KEY_ED25519_SK_CERT:
770 if (a->sk_application == NULL || b->sk_application == NULL)
771 return 0;
772 if (strcmp(a->sk_application, b->sk_application) != 0)
773 return 0;
774 /* FALLTHROUGH */
737 case KEY_ED25519: 775 case KEY_ED25519:
738 case KEY_ED25519_CERT: 776 case KEY_ED25519_CERT:
739 return a->ed25519_pk != NULL && b->ed25519_pk != NULL && 777 return a->ed25519_pk != NULL && b->ed25519_pk != NULL &&
@@ -842,12 +880,18 @@ to_blob_buf(const struct sshkey *key, struct sshbuf *b, int force_plain,
842 break; 880 break;
843#endif /* WITH_OPENSSL */ 881#endif /* WITH_OPENSSL */
844 case KEY_ED25519: 882 case KEY_ED25519:
883 case KEY_ED25519_SK:
845 if (key->ed25519_pk == NULL) 884 if (key->ed25519_pk == NULL)
846 return SSH_ERR_INVALID_ARGUMENT; 885 return SSH_ERR_INVALID_ARGUMENT;
847 if ((ret = sshbuf_put_cstring(b, typename)) != 0 || 886 if ((ret = sshbuf_put_cstring(b, typename)) != 0 ||
848 (ret = sshbuf_put_string(b, 887 (ret = sshbuf_put_string(b,
849 key->ed25519_pk, ED25519_PK_SZ)) != 0) 888 key->ed25519_pk, ED25519_PK_SZ)) != 0)
850 return ret; 889 return ret;
890 if (type == KEY_ED25519_SK) {
891 if ((ret = sshbuf_put_cstring(b,
892 key->sk_application)) != 0)
893 return ret;
894 }
851 break; 895 break;
852#ifdef WITH_XMSS 896#ifdef WITH_XMSS
853 case KEY_XMSS: 897 case KEY_XMSS:
@@ -1290,11 +1334,13 @@ sshkey_read(struct sshkey *ret, char **cpp)
1290 case KEY_ECDSA: 1334 case KEY_ECDSA:
1291 case KEY_ECDSA_SK: 1335 case KEY_ECDSA_SK:
1292 case KEY_ED25519: 1336 case KEY_ED25519:
1337 case KEY_ED25519_SK:
1293 case KEY_DSA_CERT: 1338 case KEY_DSA_CERT:
1294 case KEY_ECDSA_CERT: 1339 case KEY_ECDSA_CERT:
1295 case KEY_ECDSA_SK_CERT: 1340 case KEY_ECDSA_SK_CERT:
1296 case KEY_RSA_CERT: 1341 case KEY_RSA_CERT:
1297 case KEY_ED25519_CERT: 1342 case KEY_ED25519_CERT:
1343 case KEY_ED25519_SK_CERT:
1298#ifdef WITH_XMSS 1344#ifdef WITH_XMSS
1299 case KEY_XMSS: 1345 case KEY_XMSS:
1300 case KEY_XMSS_CERT: 1346 case KEY_XMSS_CERT:
@@ -1418,6 +1464,13 @@ sshkey_read(struct sshkey *ret, char **cpp)
1418 /* XXX */ 1464 /* XXX */
1419#endif 1465#endif
1420 break; 1466 break;
1467 case KEY_ED25519_SK:
1468 freezero(ret->ed25519_pk, ED25519_PK_SZ);
1469 ret->ed25519_pk = k->ed25519_pk;
1470 ret->sk_application = k->sk_application;
1471 k->ed25519_pk = NULL;
1472 k->sk_application = NULL;
1473 break;
1421#ifdef WITH_XMSS 1474#ifdef WITH_XMSS
1422 case KEY_XMSS: 1475 case KEY_XMSS:
1423 free(ret->xmss_pk); 1476 free(ret->xmss_pk);
@@ -1876,6 +1929,8 @@ sshkey_from_private(const struct sshkey *k, struct sshkey **pkp)
1876#endif /* WITH_OPENSSL */ 1929#endif /* WITH_OPENSSL */
1877 case KEY_ED25519: 1930 case KEY_ED25519:
1878 case KEY_ED25519_CERT: 1931 case KEY_ED25519_CERT:
1932 case KEY_ED25519_SK:
1933 case KEY_ED25519_SK_CERT:
1879 if (k->ed25519_pk != NULL) { 1934 if (k->ed25519_pk != NULL) {
1880 if ((n->ed25519_pk = malloc(ED25519_PK_SZ)) == NULL) { 1935 if ((n->ed25519_pk = malloc(ED25519_PK_SZ)) == NULL) {
1881 r = SSH_ERR_ALLOC_FAIL; 1936 r = SSH_ERR_ALLOC_FAIL;
@@ -1883,6 +1938,12 @@ sshkey_from_private(const struct sshkey *k, struct sshkey **pkp)
1883 } 1938 }
1884 memcpy(n->ed25519_pk, k->ed25519_pk, ED25519_PK_SZ); 1939 memcpy(n->ed25519_pk, k->ed25519_pk, ED25519_PK_SZ);
1885 } 1940 }
1941 if (k->type != KEY_ED25519_SK &&
1942 k->type != KEY_ED25519_SK_CERT)
1943 break;
1944 /* Append security-key application string */
1945 if ((n->sk_application = strdup(k->sk_application)) == NULL)
1946 goto out;
1886 break; 1947 break;
1887#ifdef WITH_XMSS 1948#ifdef WITH_XMSS
1888 case KEY_XMSS: 1949 case KEY_XMSS:
@@ -2444,6 +2505,7 @@ sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp,
2444# endif /* OPENSSL_HAS_ECC */ 2505# endif /* OPENSSL_HAS_ECC */
2445#endif /* WITH_OPENSSL */ 2506#endif /* WITH_OPENSSL */
2446 case KEY_ED25519_CERT: 2507 case KEY_ED25519_CERT:
2508 case KEY_ED25519_SK_CERT:
2447 /* Skip nonce */ 2509 /* Skip nonce */
2448 if (sshbuf_get_string_direct(b, NULL, NULL) != 0) { 2510 if (sshbuf_get_string_direct(b, NULL, NULL) != 0) {
2449 ret = SSH_ERR_INVALID_FORMAT; 2511 ret = SSH_ERR_INVALID_FORMAT;
@@ -2451,6 +2513,7 @@ sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp,
2451 } 2513 }
2452 /* FALLTHROUGH */ 2514 /* FALLTHROUGH */
2453 case KEY_ED25519: 2515 case KEY_ED25519:
2516 case KEY_ED25519_SK:
2454 if ((ret = sshbuf_get_string(b, &pk, &len)) != 0) 2517 if ((ret = sshbuf_get_string(b, &pk, &len)) != 0)
2455 goto out; 2518 goto out;
2456 if (len != ED25519_PK_SZ) { 2519 if (len != ED25519_PK_SZ) {
@@ -2461,6 +2524,17 @@ sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp,
2461 ret = SSH_ERR_ALLOC_FAIL; 2524 ret = SSH_ERR_ALLOC_FAIL;
2462 goto out; 2525 goto out;
2463 } 2526 }
2527 if (type == KEY_ED25519_SK || type == KEY_ED25519_SK_CERT) {
2528 /* Parse additional security-key application string */
2529 if (sshbuf_get_cstring(b, &key->sk_application,
2530 NULL) != 0) {
2531 ret = SSH_ERR_INVALID_FORMAT;
2532 goto out;
2533 }
2534#ifdef DEBUG_PK
2535 fprintf(stderr, "App: %s\n", key->sk_application);
2536#endif
2537 }
2464 key->ed25519_pk = pk; 2538 key->ed25519_pk = pk;
2465 pk = NULL; 2539 pk = NULL;
2466 break; 2540 break;
@@ -2790,6 +2864,9 @@ sshkey_to_certified(struct sshkey *k)
2790 newtype = KEY_ECDSA_SK_CERT; 2864 newtype = KEY_ECDSA_SK_CERT;
2791 break; 2865 break;
2792#endif /* WITH_OPENSSL */ 2866#endif /* WITH_OPENSSL */
2867 case KEY_ED25519_SK:
2868 newtype = KEY_ED25519_SK_CERT;
2869 break;
2793 case KEY_ED25519: 2870 case KEY_ED25519:
2794 newtype = KEY_ED25519_CERT; 2871 newtype = KEY_ED25519_CERT;
2795 break; 2872 break;
@@ -3223,6 +3300,29 @@ sshkey_private_serialize_opt(struct sshkey *key, struct sshbuf *buf,
3223 ED25519_SK_SZ)) != 0) 3300 ED25519_SK_SZ)) != 0)
3224 goto out; 3301 goto out;
3225 break; 3302 break;
3303 case KEY_ED25519_SK:
3304 if ((r = sshbuf_put_string(b, key->ed25519_pk,
3305 ED25519_PK_SZ)) != 0 ||
3306 (r = sshbuf_put_cstring(b, key->sk_application)) != 0 ||
3307 (r = sshbuf_put_u8(b, key->sk_flags)) != 0 ||
3308 (r = sshbuf_put_stringb(b, key->sk_key_handle)) != 0 ||
3309 (r = sshbuf_put_stringb(b, key->sk_reserved)) != 0)
3310 goto out;
3311 break;
3312 case KEY_ED25519_SK_CERT:
3313 if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) {
3314 r = SSH_ERR_INVALID_ARGUMENT;
3315 goto out;
3316 }
3317 if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 ||
3318 (r = sshbuf_put_string(b, key->ed25519_pk,
3319 ED25519_PK_SZ)) != 0 ||
3320 (r = sshbuf_put_cstring(b, key->sk_application)) != 0 ||
3321 (r = sshbuf_put_u8(b, key->sk_flags)) != 0 ||
3322 (r = sshbuf_put_stringb(b, key->sk_key_handle)) != 0 ||
3323 (r = sshbuf_put_stringb(b, key->sk_reserved)) != 0)
3324 goto out;
3325 break;
3226#ifdef WITH_XMSS 3326#ifdef WITH_XMSS
3227 case KEY_XMSS: 3327 case KEY_XMSS:
3228 if (key->xmss_name == NULL) { 3328 if (key->xmss_name == NULL) {
@@ -3532,6 +3632,57 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp)
3532 k->ed25519_sk = ed25519_sk; 3632 k->ed25519_sk = ed25519_sk;
3533 ed25519_pk = ed25519_sk = NULL; /* transferred */ 3633 ed25519_pk = ed25519_sk = NULL; /* transferred */
3534 break; 3634 break;
3635 case KEY_ED25519_SK:
3636 if ((k = sshkey_new(type)) == NULL) {
3637 r = SSH_ERR_ALLOC_FAIL;
3638 goto out;
3639 }
3640 if ((r = sshbuf_get_string(buf, &ed25519_pk, &pklen)) != 0)
3641 goto out;
3642 if (pklen != ED25519_PK_SZ) {
3643 r = SSH_ERR_INVALID_FORMAT;
3644 goto out;
3645 }
3646 if ((k->sk_key_handle = sshbuf_new()) == NULL ||
3647 (k->sk_reserved = sshbuf_new()) == NULL) {
3648 r = SSH_ERR_ALLOC_FAIL;
3649 goto out;
3650 }
3651 if ((r = sshbuf_get_cstring(buf, &k->sk_application,
3652 NULL)) != 0 ||
3653 (r = sshbuf_get_u8(buf, &k->sk_flags)) != 0 ||
3654 (r = sshbuf_get_stringb(buf, k->sk_key_handle)) != 0 ||
3655 (r = sshbuf_get_stringb(buf, k->sk_reserved)) != 0)
3656 goto out;
3657 k->ed25519_pk = ed25519_pk;
3658 ed25519_pk = NULL;
3659 break;
3660 case KEY_ED25519_SK_CERT:
3661 if ((r = sshkey_froms(buf, &k)) != 0 ||
3662 (r = sshbuf_get_string(buf, &ed25519_pk, &pklen)) != 0)
3663 goto out;
3664 if (k->type != type) {
3665 r = SSH_ERR_INVALID_FORMAT;
3666 goto out;
3667 }
3668 if (pklen != ED25519_PK_SZ) {
3669 r = SSH_ERR_INVALID_FORMAT;
3670 goto out;
3671 }
3672 if ((k->sk_key_handle = sshbuf_new()) == NULL ||
3673 (k->sk_reserved = sshbuf_new()) == NULL) {
3674 r = SSH_ERR_ALLOC_FAIL;
3675 goto out;
3676 }
3677 if ((r = sshbuf_get_cstring(buf, &k->sk_application,
3678 NULL)) != 0 ||
3679 (r = sshbuf_get_u8(buf, &k->sk_flags)) != 0 ||
3680 (r = sshbuf_get_stringb(buf, k->sk_key_handle)) != 0 ||
3681 (r = sshbuf_get_stringb(buf, k->sk_reserved)) != 0)
3682 goto out;
3683 k->ed25519_pk = ed25519_pk;
3684 ed25519_pk = NULL; /* transferred */
3685 break;
3535#ifdef WITH_XMSS 3686#ifdef WITH_XMSS
3536 case KEY_XMSS: 3687 case KEY_XMSS:
3537 if ((k = sshkey_new(type)) == NULL) { 3688 if ((k = sshkey_new(type)) == NULL) {
@@ -4261,6 +4412,7 @@ sshkey_private_to_fileblob(struct sshkey *key, struct sshbuf *blob,
4261 break; /* see below */ 4412 break; /* see below */
4262#endif /* WITH_OPENSSL */ 4413#endif /* WITH_OPENSSL */
4263 case KEY_ED25519: 4414 case KEY_ED25519:
4415 case KEY_ED25519_SK:
4264#ifdef WITH_XMSS 4416#ifdef WITH_XMSS
4265 case KEY_XMSS: 4417 case KEY_XMSS:
4266#endif /* WITH_XMSS */ 4418#endif /* WITH_XMSS */