1 /* $NetBSD: sshkey.c,v 1.34 2024/09/24 21:32:19 christos Exp $ */ 2 /* $OpenBSD: sshkey.c,v 1.146 2024/09/04 05:33:34 djm Exp $ */ 3 4 /* 5 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. 6 * Copyright (c) 2008 Alexander von Gernler. All rights reserved. 7 * Copyright (c) 2010,2011 Damien Miller. All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 #include "includes.h" 30 __RCSID("$NetBSD: sshkey.c,v 1.34 2024/09/24 21:32:19 christos Exp $"); 31 32 #include <sys/types.h> 33 #include <sys/mman.h> 34 #include <netinet/in.h> 35 36 #ifdef WITH_OPENSSL 37 #include <openssl/evp.h> 38 #include <openssl/err.h> 39 #include <openssl/pem.h> 40 #endif 41 42 #ifndef MAP_CONCEAL 43 #define MAP_CONCEAL 0 44 #endif 45 46 #include "crypto_api.h" 47 48 #include <errno.h> 49 #include <stdio.h> 50 #include <stdlib.h> 51 #include <string.h> 52 #include <util.h> 53 #include <limits.h> 54 #include <resolv.h> 55 56 #include "ssh2.h" 57 #include "ssherr.h" 58 #include "misc.h" 59 #include "sshbuf.h" 60 #include "cipher.h" 61 #include "digest.h" 62 #define SSHKEY_INTERNAL 63 #include "sshkey.h" 64 #include "match.h" 65 #include "ssh-sk.h" 66 67 #ifdef WITH_XMSS 68 #include "sshkey-xmss.h" 69 #include "xmss_fast.h" 70 #endif 71 72 /* openssh private key file format */ 73 #define MARK_BEGIN "-----BEGIN OPENSSH PRIVATE KEY-----\n" 74 #define MARK_END "-----END OPENSSH PRIVATE KEY-----\n" 75 #define MARK_BEGIN_LEN (sizeof(MARK_BEGIN) - 1) 76 #define MARK_END_LEN (sizeof(MARK_END) - 1) 77 #define KDFNAME "bcrypt" 78 #define AUTH_MAGIC "openssh-key-v1" 79 #define SALT_LEN 16 80 #define DEFAULT_CIPHERNAME "aes256-ctr" 81 #define DEFAULT_ROUNDS 24 82 83 /* Version identification string for SSH v1 identity files. */ 84 #define LEGACY_BEGIN "SSH PRIVATE KEY FILE FORMAT 1.1\n" 85 86 /* 87 * Constants relating to "shielding" support; protection of keys expected 88 * to remain in memory for long durations 89 */ 90 #define SSHKEY_SHIELD_PREKEY_LEN (16 * 1024) 91 #define SSHKEY_SHIELD_CIPHER "aes256-ctr" /* XXX want AES-EME* */ 92 #define SSHKEY_SHIELD_PREKEY_HASH SSH_DIGEST_SHA512 93 94 int sshkey_private_serialize_opt(struct sshkey *key, 95 struct sshbuf *buf, enum sshkey_serialize_rep); 96 static int sshkey_from_blob_internal(struct sshbuf *buf, 97 struct sshkey **keyp, int allow_cert); 98 99 /* Supported key types */ 100 extern const struct sshkey_impl sshkey_ed25519_impl; 101 extern const struct sshkey_impl sshkey_ed25519_cert_impl; 102 extern const struct sshkey_impl sshkey_ed25519_sk_impl; 103 extern const struct sshkey_impl sshkey_ed25519_sk_cert_impl; 104 #ifdef WITH_OPENSSL 105 extern const struct sshkey_impl sshkey_ecdsa_sk_impl; 106 extern const struct sshkey_impl sshkey_ecdsa_sk_cert_impl; 107 extern const struct sshkey_impl sshkey_ecdsa_sk_webauthn_impl; 108 extern const struct sshkey_impl sshkey_ecdsa_nistp256_impl; 109 extern const struct sshkey_impl sshkey_ecdsa_nistp256_cert_impl; 110 extern const struct sshkey_impl sshkey_ecdsa_nistp384_impl; 111 extern const struct sshkey_impl sshkey_ecdsa_nistp384_cert_impl; 112 extern const struct sshkey_impl sshkey_ecdsa_nistp521_impl; 113 extern const struct sshkey_impl sshkey_ecdsa_nistp521_cert_impl; 114 extern const struct sshkey_impl sshkey_rsa_impl; 115 extern const struct sshkey_impl sshkey_rsa_cert_impl; 116 extern const struct sshkey_impl sshkey_rsa_sha256_impl; 117 extern const struct sshkey_impl sshkey_rsa_sha256_cert_impl; 118 extern const struct sshkey_impl sshkey_rsa_sha512_impl; 119 extern const struct sshkey_impl sshkey_rsa_sha512_cert_impl; 120 # ifdef WITH_DSA 121 extern const struct sshkey_impl sshkey_dss_impl; 122 extern const struct sshkey_impl sshkey_dsa_cert_impl; 123 # endif 124 #endif /* WITH_OPENSSL */ 125 #ifdef WITH_XMSS 126 extern const struct sshkey_impl sshkey_xmss_impl; 127 extern const struct sshkey_impl sshkey_xmss_cert_impl; 128 #endif 129 130 const struct sshkey_impl * const keyimpls[] = { 131 &sshkey_ed25519_impl, 132 &sshkey_ed25519_cert_impl, 133 &sshkey_ed25519_sk_impl, 134 &sshkey_ed25519_sk_cert_impl, 135 #ifdef WITH_OPENSSL 136 &sshkey_ecdsa_nistp256_impl, 137 &sshkey_ecdsa_nistp256_cert_impl, 138 &sshkey_ecdsa_nistp384_impl, 139 &sshkey_ecdsa_nistp384_cert_impl, 140 &sshkey_ecdsa_nistp521_impl, 141 &sshkey_ecdsa_nistp521_cert_impl, 142 &sshkey_ecdsa_sk_impl, 143 &sshkey_ecdsa_sk_cert_impl, 144 &sshkey_ecdsa_sk_webauthn_impl, 145 # ifdef WITH_DSA 146 &sshkey_dss_impl, 147 &sshkey_dsa_cert_impl, 148 # endif 149 &sshkey_rsa_impl, 150 &sshkey_rsa_cert_impl, 151 &sshkey_rsa_sha256_impl, 152 &sshkey_rsa_sha256_cert_impl, 153 &sshkey_rsa_sha512_impl, 154 &sshkey_rsa_sha512_cert_impl, 155 #endif /* WITH_OPENSSL */ 156 #ifdef WITH_XMSS 157 &sshkey_xmss_impl, 158 &sshkey_xmss_cert_impl, 159 #endif 160 NULL 161 }; 162 163 static const struct sshkey_impl * 164 sshkey_impl_from_type(int type) 165 { 166 int i; 167 168 for (i = 0; keyimpls[i] != NULL; i++) { 169 if (keyimpls[i]->type == type) 170 return keyimpls[i]; 171 } 172 return NULL; 173 } 174 175 static const struct sshkey_impl * 176 sshkey_impl_from_type_nid(int type, int nid) 177 { 178 int i; 179 180 for (i = 0; keyimpls[i] != NULL; i++) { 181 if (keyimpls[i]->type == type && 182 (keyimpls[i]->nid == 0 || keyimpls[i]->nid == nid)) 183 return keyimpls[i]; 184 } 185 return NULL; 186 } 187 188 static const struct sshkey_impl * 189 sshkey_impl_from_key(const struct sshkey *k) 190 { 191 if (k == NULL) 192 return NULL; 193 return sshkey_impl_from_type_nid(k->type, k->ecdsa_nid); 194 } 195 196 const char * 197 sshkey_type(const struct sshkey *k) 198 { 199 const struct sshkey_impl *impl; 200 201 if ((impl = sshkey_impl_from_key(k)) == NULL) 202 return "unknown"; 203 return impl->shortname; 204 } 205 206 static const char * 207 sshkey_ssh_name_from_type_nid(int type, int nid) 208 { 209 const struct sshkey_impl *impl; 210 211 if ((impl = sshkey_impl_from_type_nid(type, nid)) == NULL) 212 return "ssh-unknown"; 213 return impl->name; 214 } 215 216 int 217 sshkey_type_is_cert(int type) 218 { 219 const struct sshkey_impl *impl; 220 221 if ((impl = sshkey_impl_from_type(type)) == NULL) 222 return 0; 223 return impl->cert; 224 } 225 226 const char * 227 sshkey_ssh_name(const struct sshkey *k) 228 { 229 return sshkey_ssh_name_from_type_nid(k->type, k->ecdsa_nid); 230 } 231 232 const char * 233 sshkey_ssh_name_plain(const struct sshkey *k) 234 { 235 return sshkey_ssh_name_from_type_nid(sshkey_type_plain(k->type), 236 k->ecdsa_nid); 237 } 238 239 static int 240 type_from_name(const char *name, int allow_short) 241 { 242 int i; 243 const struct sshkey_impl *impl; 244 245 for (i = 0; keyimpls[i] != NULL; i++) { 246 impl = keyimpls[i]; 247 if (impl->name != NULL && strcmp(name, impl->name) == 0) 248 return impl->type; 249 /* Only allow shortname matches for plain key types */ 250 if (allow_short && !impl->cert && impl->shortname != NULL && 251 strcasecmp(impl->shortname, name) == 0) 252 return impl->type; 253 } 254 return KEY_UNSPEC; 255 } 256 257 int 258 sshkey_type_from_name(const char *name) 259 { 260 return type_from_name(name, 0); 261 } 262 263 int 264 sshkey_type_from_shortname(const char *name) 265 { 266 return type_from_name(name, 1); 267 } 268 269 static int 270 key_type_is_ecdsa_variant(int type) 271 { 272 switch (type) { 273 case KEY_ECDSA: 274 case KEY_ECDSA_CERT: 275 case KEY_ECDSA_SK: 276 case KEY_ECDSA_SK_CERT: 277 return 1; 278 } 279 return 0; 280 } 281 282 int 283 sshkey_ecdsa_nid_from_name(const char *name) 284 { 285 int i; 286 287 for (i = 0; keyimpls[i] != NULL; i++) { 288 if (!key_type_is_ecdsa_variant(keyimpls[i]->type)) 289 continue; 290 if (keyimpls[i]->name != NULL && 291 strcmp(name, keyimpls[i]->name) == 0) 292 return keyimpls[i]->nid; 293 } 294 return -1; 295 } 296 297 int 298 sshkey_match_keyname_to_sigalgs(const char *keyname, const char *sigalgs) 299 { 300 int ktype; 301 302 if (sigalgs == NULL || *sigalgs == '\0' || 303 (ktype = sshkey_type_from_name(keyname)) == KEY_UNSPEC) 304 return 0; 305 else if (ktype == KEY_RSA) { 306 return match_pattern_list("ssh-rsa", sigalgs, 0) == 1 || 307 match_pattern_list("rsa-sha2-256", sigalgs, 0) == 1 || 308 match_pattern_list("rsa-sha2-512", sigalgs, 0) == 1; 309 } else if (ktype == KEY_RSA_CERT) { 310 return match_pattern_list("ssh-rsa-cert-v01@openssh.com", 311 sigalgs, 0) == 1 || 312 match_pattern_list("rsa-sha2-256-cert-v01@openssh.com", 313 sigalgs, 0) == 1 || 314 match_pattern_list("rsa-sha2-512-cert-v01@openssh.com", 315 sigalgs, 0) == 1; 316 } else 317 return match_pattern_list(keyname, sigalgs, 0) == 1; 318 } 319 320 char * 321 sshkey_alg_list(int certs_only, int plain_only, int include_sigonly, char sep) 322 { 323 char *tmp, *ret = NULL; 324 size_t i, nlen, rlen = 0; 325 const struct sshkey_impl *impl; 326 327 for (i = 0; keyimpls[i] != NULL; i++) { 328 impl = keyimpls[i]; 329 if (impl->name == NULL) 330 continue; 331 if (!include_sigonly && impl->sigonly) 332 continue; 333 if ((certs_only && !impl->cert) || (plain_only && impl->cert)) 334 continue; 335 if (ret != NULL) 336 ret[rlen++] = sep; 337 nlen = strlen(impl->name); 338 if ((tmp = realloc(ret, rlen + nlen + 2)) == NULL) { 339 free(ret); 340 return NULL; 341 } 342 ret = tmp; 343 memcpy(ret + rlen, impl->name, nlen + 1); 344 rlen += nlen; 345 } 346 return ret; 347 } 348 349 int 350 sshkey_names_valid2(const char *names, int allow_wildcard, int plain_only) 351 { 352 char *s, *cp, *p; 353 const struct sshkey_impl *impl; 354 int i, type; 355 356 if (names == NULL || strcmp(names, "") == 0) 357 return 0; 358 if ((s = cp = strdup(names)) == NULL) 359 return 0; 360 for ((p = strsep(&cp, ",")); p && *p != '\0'; 361 (p = strsep(&cp, ","))) { 362 type = sshkey_type_from_name(p); 363 if (type == KEY_UNSPEC) { 364 if (allow_wildcard) { 365 /* 366 * Try matching key types against the string. 367 * If any has a positive or negative match then 368 * the component is accepted. 369 */ 370 impl = NULL; 371 for (i = 0; keyimpls[i] != NULL; i++) { 372 if (match_pattern_list( 373 keyimpls[i]->name, p, 0) != 0) { 374 impl = keyimpls[i]; 375 break; 376 } 377 } 378 if (impl != NULL) 379 continue; 380 } 381 free(s); 382 return 0; 383 } else if (plain_only && sshkey_type_is_cert(type)) { 384 free(s); 385 return 0; 386 } 387 } 388 free(s); 389 return 1; 390 } 391 392 u_int 393 sshkey_size(const struct sshkey *k) 394 { 395 const struct sshkey_impl *impl; 396 397 if ((impl = sshkey_impl_from_key(k)) == NULL) 398 return 0; 399 if (impl->funcs->size != NULL) 400 return impl->funcs->size(k); 401 return impl->keybits; 402 } 403 404 static int 405 sshkey_type_is_valid_ca(int type) 406 { 407 const struct sshkey_impl *impl; 408 409 if ((impl = sshkey_impl_from_type(type)) == NULL) 410 return 0; 411 /* All non-certificate types may act as CAs */ 412 return !impl->cert; 413 } 414 415 int 416 sshkey_is_cert(const struct sshkey *k) 417 { 418 if (k == NULL) 419 return 0; 420 return sshkey_type_is_cert(k->type); 421 } 422 423 int 424 sshkey_is_sk(const struct sshkey *k) 425 { 426 if (k == NULL) 427 return 0; 428 switch (sshkey_type_plain(k->type)) { 429 case KEY_ECDSA_SK: 430 case KEY_ED25519_SK: 431 return 1; 432 default: 433 return 0; 434 } 435 } 436 437 /* Return the cert-less equivalent to a certified key type */ 438 int 439 sshkey_type_plain(int type) 440 { 441 switch (type) { 442 case KEY_RSA_CERT: 443 return KEY_RSA; 444 case KEY_DSA_CERT: 445 return KEY_DSA; 446 case KEY_ECDSA_CERT: 447 return KEY_ECDSA; 448 case KEY_ECDSA_SK_CERT: 449 return KEY_ECDSA_SK; 450 case KEY_ED25519_CERT: 451 return KEY_ED25519; 452 case KEY_ED25519_SK_CERT: 453 return KEY_ED25519_SK; 454 case KEY_XMSS_CERT: 455 return KEY_XMSS; 456 default: 457 return type; 458 } 459 } 460 461 /* Return the cert equivalent to a plain key type */ 462 static int 463 sshkey_type_certified(int type) 464 { 465 switch (type) { 466 case KEY_RSA: 467 return KEY_RSA_CERT; 468 case KEY_DSA: 469 return KEY_DSA_CERT; 470 case KEY_ECDSA: 471 return KEY_ECDSA_CERT; 472 case KEY_ECDSA_SK: 473 return KEY_ECDSA_SK_CERT; 474 case KEY_ED25519: 475 return KEY_ED25519_CERT; 476 case KEY_ED25519_SK: 477 return KEY_ED25519_SK_CERT; 478 case KEY_XMSS: 479 return KEY_XMSS_CERT; 480 default: 481 return -1; 482 } 483 } 484 485 #ifdef WITH_OPENSSL 486 static const EVP_MD * 487 ssh_digest_to_md(int hash_alg) 488 { 489 switch (hash_alg) { 490 case SSH_DIGEST_SHA1: 491 return EVP_sha1(); 492 case SSH_DIGEST_SHA256: 493 return EVP_sha256(); 494 case SSH_DIGEST_SHA384: 495 return EVP_sha384(); 496 case SSH_DIGEST_SHA512: 497 return EVP_sha512(); 498 } 499 return NULL; 500 } 501 502 int 503 sshkey_pkey_digest_sign(EVP_PKEY *pkey, int hash_alg, u_char **sigp, 504 size_t *lenp, const u_char *data, size_t datalen) 505 { 506 EVP_MD_CTX *ctx = NULL; 507 u_char *sig = NULL; 508 int ret; 509 size_t slen; 510 const EVP_MD *evpmd; 511 512 *sigp = NULL; 513 *lenp = 0; 514 515 slen = EVP_PKEY_size(pkey); 516 if (slen <= 0 || slen > SSHBUF_MAX_BIGNUM || 517 (evpmd = ssh_digest_to_md(hash_alg)) == NULL) 518 return SSH_ERR_INVALID_ARGUMENT; 519 520 if ((sig = malloc(slen)) == NULL) 521 return SSH_ERR_ALLOC_FAIL; 522 523 if ((ctx = EVP_MD_CTX_new()) == NULL) { 524 ret = SSH_ERR_ALLOC_FAIL; 525 goto out; 526 } 527 if (EVP_DigestSignInit(ctx, NULL, evpmd, NULL, pkey) != 1 || 528 EVP_DigestSign(ctx, sig, &slen, data, datalen) != 1) { 529 ret = SSH_ERR_LIBCRYPTO_ERROR; 530 goto out; 531 } 532 533 *sigp = sig; 534 *lenp = slen; 535 /* Now owned by the caller */ 536 sig = NULL; 537 ret = 0; 538 539 out: 540 EVP_MD_CTX_free(ctx); 541 free(sig); 542 return ret; 543 } 544 545 int 546 sshkey_pkey_digest_verify(EVP_PKEY *pkey, int hash_alg, const u_char *data, 547 size_t datalen, u_char *sigbuf, size_t siglen) 548 { 549 EVP_MD_CTX *ctx = NULL; 550 int ret = SSH_ERR_INTERNAL_ERROR; 551 const EVP_MD *evpmd; 552 553 if ((evpmd = ssh_digest_to_md(hash_alg)) == NULL) 554 return SSH_ERR_INVALID_ARGUMENT; 555 if ((ctx = EVP_MD_CTX_new()) == NULL) 556 return SSH_ERR_ALLOC_FAIL; 557 if (EVP_DigestVerifyInit(ctx, NULL, evpmd, NULL, pkey) != 1) { 558 ret = SSH_ERR_LIBCRYPTO_ERROR; 559 goto out; 560 } 561 switch (EVP_DigestVerify(ctx, sigbuf, siglen, data, datalen)) { 562 case 1: 563 ret = 0; 564 break; 565 case 0: 566 ret = SSH_ERR_SIGNATURE_INVALID; 567 break; 568 default: 569 ret = SSH_ERR_LIBCRYPTO_ERROR; 570 break; 571 } 572 573 out: 574 EVP_MD_CTX_free(ctx); 575 return ret; 576 } 577 578 /* XXX: these are really begging for a table-driven approach */ 579 int 580 sshkey_curve_name_to_nid(const char *name) 581 { 582 if (strcmp(name, "nistp256") == 0) 583 return NID_X9_62_prime256v1; 584 else if (strcmp(name, "nistp384") == 0) 585 return NID_secp384r1; 586 else if (strcmp(name, "nistp521") == 0) 587 return NID_secp521r1; 588 else 589 return -1; 590 } 591 592 u_int 593 sshkey_curve_nid_to_bits(int nid) 594 { 595 switch (nid) { 596 case NID_X9_62_prime256v1: 597 return 256; 598 case NID_secp384r1: 599 return 384; 600 case NID_secp521r1: 601 return 521; 602 default: 603 return 0; 604 } 605 } 606 607 int 608 sshkey_ecdsa_bits_to_nid(int bits) 609 { 610 switch (bits) { 611 case 256: 612 return NID_X9_62_prime256v1; 613 case 384: 614 return NID_secp384r1; 615 case 521: 616 return NID_secp521r1; 617 default: 618 return -1; 619 } 620 } 621 622 const char * 623 sshkey_curve_nid_to_name(int nid) 624 { 625 switch (nid) { 626 case NID_X9_62_prime256v1: 627 return "nistp256"; 628 case NID_secp384r1: 629 return "nistp384"; 630 case NID_secp521r1: 631 return "nistp521"; 632 default: 633 return NULL; 634 } 635 } 636 637 int 638 sshkey_ec_nid_to_hash_alg(int nid) 639 { 640 int kbits = sshkey_curve_nid_to_bits(nid); 641 642 if (kbits <= 0) 643 return -1; 644 645 /* RFC5656 section 6.2.1 */ 646 if (kbits <= 256) 647 return SSH_DIGEST_SHA256; 648 else if (kbits <= 384) 649 return SSH_DIGEST_SHA384; 650 else 651 return SSH_DIGEST_SHA512; 652 } 653 #endif /* WITH_OPENSSL */ 654 655 static void 656 cert_free(struct sshkey_cert *cert) 657 { 658 u_int i; 659 660 if (cert == NULL) 661 return; 662 sshbuf_free(cert->certblob); 663 sshbuf_free(cert->critical); 664 sshbuf_free(cert->extensions); 665 free(cert->key_id); 666 for (i = 0; i < cert->nprincipals; i++) 667 free(cert->principals[i]); 668 free(cert->principals); 669 sshkey_free(cert->signature_key); 670 free(cert->signature_type); 671 freezero(cert, sizeof(*cert)); 672 } 673 674 static struct sshkey_cert * 675 cert_new(void) 676 { 677 struct sshkey_cert *cert; 678 679 if ((cert = calloc(1, sizeof(*cert))) == NULL) 680 return NULL; 681 if ((cert->certblob = sshbuf_new()) == NULL || 682 (cert->critical = sshbuf_new()) == NULL || 683 (cert->extensions = sshbuf_new()) == NULL) { 684 cert_free(cert); 685 return NULL; 686 } 687 cert->key_id = NULL; 688 cert->principals = NULL; 689 cert->signature_key = NULL; 690 cert->signature_type = NULL; 691 return cert; 692 } 693 694 struct sshkey * 695 sshkey_new(int type) 696 { 697 struct sshkey *k; 698 const struct sshkey_impl *impl = NULL; 699 700 if (type != KEY_UNSPEC && 701 (impl = sshkey_impl_from_type(type)) == NULL) 702 return NULL; 703 704 /* All non-certificate types may act as CAs */ 705 if ((k = calloc(1, sizeof(*k))) == NULL) 706 return NULL; 707 k->type = type; 708 k->ecdsa_nid = -1; 709 if (impl != NULL && impl->funcs->alloc != NULL) { 710 if (impl->funcs->alloc(k) != 0) { 711 free(k); 712 return NULL; 713 } 714 } 715 if (sshkey_is_cert(k)) { 716 if ((k->cert = cert_new()) == NULL) { 717 sshkey_free(k); 718 return NULL; 719 } 720 } 721 722 return k; 723 } 724 725 /* Frees common FIDO fields */ 726 void 727 sshkey_sk_cleanup(struct sshkey *k) 728 { 729 free(k->sk_application); 730 sshbuf_free(k->sk_key_handle); 731 sshbuf_free(k->sk_reserved); 732 k->sk_application = NULL; 733 k->sk_key_handle = k->sk_reserved = NULL; 734 } 735 736 static int 737 sshkey_prekey_alloc(u_char **prekeyp, size_t len) 738 { 739 u_char *prekey; 740 741 *prekeyp = NULL; 742 if ((prekey = mmap(NULL, len, PROT_READ|PROT_WRITE, 743 MAP_ANON|MAP_PRIVATE|MAP_CONCEAL, -1, 0)) == MAP_FAILED) 744 return SSH_ERR_SYSTEM_ERROR; 745 *prekeyp = prekey; 746 return 0; 747 } 748 749 static void 750 sshkey_prekey_free(void *prekey, size_t len) 751 { 752 if (prekey == NULL) 753 return; 754 munmap(prekey, len); 755 } 756 757 static void 758 sshkey_free_contents(struct sshkey *k) 759 { 760 const struct sshkey_impl *impl; 761 762 if (k == NULL) 763 return; 764 if ((impl = sshkey_impl_from_type(k->type)) != NULL && 765 impl->funcs->cleanup != NULL) 766 impl->funcs->cleanup(k); 767 if (sshkey_is_cert(k)) 768 cert_free(k->cert); 769 freezero(k->shielded_private, k->shielded_len); 770 sshkey_prekey_free(k->shield_prekey, k->shield_prekey_len); 771 } 772 773 void 774 sshkey_free(struct sshkey *k) 775 { 776 sshkey_free_contents(k); 777 freezero(k, sizeof(*k)); 778 } 779 780 static int 781 cert_compare(struct sshkey_cert *a, struct sshkey_cert *b) 782 { 783 if (a == NULL && b == NULL) 784 return 1; 785 if (a == NULL || b == NULL) 786 return 0; 787 if (sshbuf_len(a->certblob) != sshbuf_len(b->certblob)) 788 return 0; 789 if (timingsafe_bcmp(sshbuf_ptr(a->certblob), sshbuf_ptr(b->certblob), 790 sshbuf_len(a->certblob)) != 0) 791 return 0; 792 return 1; 793 } 794 795 /* Compares FIDO-specific pubkey fields only */ 796 int 797 sshkey_sk_fields_equal(const struct sshkey *a, const struct sshkey *b) 798 { 799 if (a->sk_application == NULL || b->sk_application == NULL) 800 return 0; 801 if (strcmp(a->sk_application, b->sk_application) != 0) 802 return 0; 803 return 1; 804 } 805 806 /* 807 * Compare public portions of key only, allowing comparisons between 808 * certificates and plain keys too. 809 */ 810 int 811 sshkey_equal_public(const struct sshkey *a, const struct sshkey *b) 812 { 813 const struct sshkey_impl *impl; 814 815 if (a == NULL || b == NULL || 816 sshkey_type_plain(a->type) != sshkey_type_plain(b->type)) 817 return 0; 818 if ((impl = sshkey_impl_from_type(a->type)) == NULL) 819 return 0; 820 return impl->funcs->equal(a, b); 821 } 822 823 int 824 sshkey_equal(const struct sshkey *a, const struct sshkey *b) 825 { 826 if (a == NULL || b == NULL || a->type != b->type) 827 return 0; 828 if (sshkey_is_cert(a)) { 829 if (!cert_compare(a->cert, b->cert)) 830 return 0; 831 } 832 return sshkey_equal_public(a, b); 833 } 834 835 836 /* Serialise common FIDO key parts */ 837 int 838 sshkey_serialize_sk(const struct sshkey *key, struct sshbuf *b) 839 { 840 int r; 841 842 if ((r = sshbuf_put_cstring(b, key->sk_application)) != 0) 843 return r; 844 845 return 0; 846 } 847 848 static int 849 to_blob_buf(const struct sshkey *key, struct sshbuf *b, int force_plain, 850 enum sshkey_serialize_rep opts) 851 { 852 int type, ret = SSH_ERR_INTERNAL_ERROR; 853 const char *typename; 854 const struct sshkey_impl *impl; 855 856 if (key == NULL) 857 return SSH_ERR_INVALID_ARGUMENT; 858 859 type = force_plain ? sshkey_type_plain(key->type) : key->type; 860 861 if (sshkey_type_is_cert(type)) { 862 if (key->cert == NULL) 863 return SSH_ERR_EXPECTED_CERT; 864 if (sshbuf_len(key->cert->certblob) == 0) 865 return SSH_ERR_KEY_LACKS_CERTBLOB; 866 /* Use the existing blob */ 867 if ((ret = sshbuf_putb(b, key->cert->certblob)) != 0) 868 return ret; 869 return 0; 870 } 871 if ((impl = sshkey_impl_from_type(type)) == NULL) 872 return SSH_ERR_KEY_TYPE_UNKNOWN; 873 874 typename = sshkey_ssh_name_from_type_nid(type, key->ecdsa_nid); 875 if ((ret = sshbuf_put_cstring(b, typename)) != 0) 876 return ret; 877 return impl->funcs->serialize_public(key, b, opts); 878 } 879 880 int 881 sshkey_putb(const struct sshkey *key, struct sshbuf *b) 882 { 883 return to_blob_buf(key, b, 0, SSHKEY_SERIALIZE_DEFAULT); 884 } 885 886 int 887 sshkey_puts_opts(const struct sshkey *key, struct sshbuf *b, 888 enum sshkey_serialize_rep opts) 889 { 890 struct sshbuf *tmp; 891 int r; 892 893 if ((tmp = sshbuf_new()) == NULL) 894 return SSH_ERR_ALLOC_FAIL; 895 r = to_blob_buf(key, tmp, 0, opts); 896 if (r == 0) 897 r = sshbuf_put_stringb(b, tmp); 898 sshbuf_free(tmp); 899 return r; 900 } 901 902 int 903 sshkey_puts(const struct sshkey *key, struct sshbuf *b) 904 { 905 return sshkey_puts_opts(key, b, SSHKEY_SERIALIZE_DEFAULT); 906 } 907 908 int 909 sshkey_putb_plain(const struct sshkey *key, struct sshbuf *b) 910 { 911 return to_blob_buf(key, b, 1, SSHKEY_SERIALIZE_DEFAULT); 912 } 913 914 static int 915 to_blob(const struct sshkey *key, u_char **blobp, size_t *lenp, int force_plain, 916 enum sshkey_serialize_rep opts) 917 { 918 int ret = SSH_ERR_INTERNAL_ERROR; 919 size_t len; 920 struct sshbuf *b = NULL; 921 922 if (lenp != NULL) 923 *lenp = 0; 924 if (blobp != NULL) 925 *blobp = NULL; 926 if ((b = sshbuf_new()) == NULL) 927 return SSH_ERR_ALLOC_FAIL; 928 if ((ret = to_blob_buf(key, b, force_plain, opts)) != 0) 929 goto out; 930 len = sshbuf_len(b); 931 if (lenp != NULL) 932 *lenp = len; 933 if (blobp != NULL) { 934 if ((*blobp = malloc(len)) == NULL) { 935 ret = SSH_ERR_ALLOC_FAIL; 936 goto out; 937 } 938 memcpy(*blobp, sshbuf_ptr(b), len); 939 } 940 ret = 0; 941 out: 942 sshbuf_free(b); 943 return ret; 944 } 945 946 int 947 sshkey_to_blob(const struct sshkey *key, u_char **blobp, size_t *lenp) 948 { 949 return to_blob(key, blobp, lenp, 0, SSHKEY_SERIALIZE_DEFAULT); 950 } 951 952 int 953 sshkey_plain_to_blob(const struct sshkey *key, u_char **blobp, size_t *lenp) 954 { 955 return to_blob(key, blobp, lenp, 1, SSHKEY_SERIALIZE_DEFAULT); 956 } 957 958 int 959 sshkey_fingerprint_raw(const struct sshkey *k, int dgst_alg, 960 u_char **retp, size_t *lenp) 961 { 962 u_char *blob = NULL, *ret = NULL; 963 size_t blob_len = 0; 964 int r = SSH_ERR_INTERNAL_ERROR; 965 966 if (retp != NULL) 967 *retp = NULL; 968 if (lenp != NULL) 969 *lenp = 0; 970 if (ssh_digest_bytes(dgst_alg) == 0) { 971 r = SSH_ERR_INVALID_ARGUMENT; 972 goto out; 973 } 974 if ((r = to_blob(k, &blob, &blob_len, 1, SSHKEY_SERIALIZE_DEFAULT)) 975 != 0) 976 goto out; 977 if ((ret = calloc(1, SSH_DIGEST_MAX_LENGTH)) == NULL) { 978 r = SSH_ERR_ALLOC_FAIL; 979 goto out; 980 } 981 if ((r = ssh_digest_memory(dgst_alg, blob, blob_len, 982 ret, SSH_DIGEST_MAX_LENGTH)) != 0) 983 goto out; 984 /* success */ 985 if (retp != NULL) { 986 *retp = ret; 987 ret = NULL; 988 } 989 if (lenp != NULL) 990 *lenp = ssh_digest_bytes(dgst_alg); 991 r = 0; 992 out: 993 free(ret); 994 if (blob != NULL) 995 freezero(blob, blob_len); 996 return r; 997 } 998 999 static char * 1000 fingerprint_b64(const char *alg, u_char *dgst_raw, size_t dgst_raw_len) 1001 { 1002 char *ret; 1003 size_t plen = strlen(alg) + 1; 1004 size_t rlen = ((dgst_raw_len + 2) / 3) * 4 + plen + 1; 1005 1006 if (dgst_raw_len > 65536 || (ret = calloc(1, rlen)) == NULL) 1007 return NULL; 1008 strlcpy(ret, alg, rlen); 1009 strlcat(ret, ":", rlen); 1010 if (dgst_raw_len == 0) 1011 return ret; 1012 if (b64_ntop(dgst_raw, dgst_raw_len, ret + plen, rlen - plen) == -1) { 1013 freezero(ret, rlen); 1014 return NULL; 1015 } 1016 /* Trim padding characters from end */ 1017 ret[strcspn(ret, "=")] = '\0'; 1018 return ret; 1019 } 1020 1021 static char * 1022 fingerprint_hex(const char *alg, u_char *dgst_raw, size_t dgst_raw_len) 1023 { 1024 char *retval, hex[5]; 1025 size_t i, rlen = dgst_raw_len * 3 + strlen(alg) + 2; 1026 1027 if (dgst_raw_len > 65536 || (retval = calloc(1, rlen)) == NULL) 1028 return NULL; 1029 strlcpy(retval, alg, rlen); 1030 strlcat(retval, ":", rlen); 1031 for (i = 0; i < dgst_raw_len; i++) { 1032 snprintf(hex, sizeof(hex), "%s%02x", 1033 i > 0 ? ":" : "", dgst_raw[i]); 1034 strlcat(retval, hex, rlen); 1035 } 1036 return retval; 1037 } 1038 1039 static char * 1040 fingerprint_bubblebabble(u_char *dgst_raw, size_t dgst_raw_len) 1041 { 1042 char vowels[] = { 'a', 'e', 'i', 'o', 'u', 'y' }; 1043 char consonants[] = { 'b', 'c', 'd', 'f', 'g', 'h', 'k', 'l', 'm', 1044 'n', 'p', 'r', 's', 't', 'v', 'z', 'x' }; 1045 u_int i, j = 0, rounds, seed = 1; 1046 char *retval; 1047 1048 rounds = (dgst_raw_len / 2) + 1; 1049 if ((retval = calloc(rounds, 6)) == NULL) 1050 return NULL; 1051 retval[j++] = 'x'; 1052 for (i = 0; i < rounds; i++) { 1053 u_int idx0, idx1, idx2, idx3, idx4; 1054 if ((i + 1 < rounds) || (dgst_raw_len % 2 != 0)) { 1055 idx0 = (((((u_int)(dgst_raw[2 * i])) >> 6) & 3) + 1056 seed) % 6; 1057 idx1 = (((u_int)(dgst_raw[2 * i])) >> 2) & 15; 1058 idx2 = ((((u_int)(dgst_raw[2 * i])) & 3) + 1059 (seed / 6)) % 6; 1060 retval[j++] = vowels[idx0]; 1061 retval[j++] = consonants[idx1]; 1062 retval[j++] = vowels[idx2]; 1063 if ((i + 1) < rounds) { 1064 idx3 = (((u_int)(dgst_raw[(2 * i) + 1])) >> 4) & 15; 1065 idx4 = (((u_int)(dgst_raw[(2 * i) + 1]))) & 15; 1066 retval[j++] = consonants[idx3]; 1067 retval[j++] = '-'; 1068 retval[j++] = consonants[idx4]; 1069 seed = ((seed * 5) + 1070 ((((u_int)(dgst_raw[2 * i])) * 7) + 1071 ((u_int)(dgst_raw[(2 * i) + 1])))) % 36; 1072 } 1073 } else { 1074 idx0 = seed % 6; 1075 idx1 = 16; 1076 idx2 = seed / 6; 1077 retval[j++] = vowels[idx0]; 1078 retval[j++] = consonants[idx1]; 1079 retval[j++] = vowels[idx2]; 1080 } 1081 } 1082 retval[j++] = 'x'; 1083 retval[j++] = '\0'; 1084 return retval; 1085 } 1086 1087 /* 1088 * Draw an ASCII-Art representing the fingerprint so human brain can 1089 * profit from its built-in pattern recognition ability. 1090 * This technique is called "random art" and can be found in some 1091 * scientific publications like this original paper: 1092 * 1093 * "Hash Visualization: a New Technique to improve Real-World Security", 1094 * Perrig A. and Song D., 1999, International Workshop on Cryptographic 1095 * Techniques and E-Commerce (CrypTEC '99) 1096 * sparrow.ece.cmu.edu/~adrian/projects/validation/validation.pdf 1097 * 1098 * The subject came up in a talk by Dan Kaminsky, too. 1099 * 1100 * If you see the picture is different, the key is different. 1101 * If the picture looks the same, you still know nothing. 1102 * 1103 * The algorithm used here is a worm crawling over a discrete plane, 1104 * leaving a trace (augmenting the field) everywhere it goes. 1105 * Movement is taken from dgst_raw 2bit-wise. Bumping into walls 1106 * makes the respective movement vector be ignored for this turn. 1107 * Graphs are not unambiguous, because circles in graphs can be 1108 * walked in either direction. 1109 */ 1110 1111 /* 1112 * Field sizes for the random art. Have to be odd, so the starting point 1113 * can be in the exact middle of the picture, and FLDBASE should be >=8 . 1114 * Else pictures would be too dense, and drawing the frame would 1115 * fail, too, because the key type would not fit in anymore. 1116 */ 1117 #define FLDBASE 8 1118 #define FLDSIZE_Y (FLDBASE + 1) 1119 #define FLDSIZE_X (FLDBASE * 2 + 1) 1120 static char * 1121 fingerprint_randomart(const char *alg, u_char *dgst_raw, size_t dgst_raw_len, 1122 const struct sshkey *k) 1123 { 1124 /* 1125 * Chars to be used after each other every time the worm 1126 * intersects with itself. Matter of taste. 1127 */ 1128 const char *augmentation_string = " .o+=*BOX@%&#/^SE"; 1129 char *retval, *p, title[FLDSIZE_X], hash[FLDSIZE_X]; 1130 u_char field[FLDSIZE_X][FLDSIZE_Y]; 1131 size_t i, tlen, hlen; 1132 u_int b; 1133 int x, y, r; 1134 size_t len = strlen(augmentation_string) - 1; 1135 1136 if ((retval = calloc((FLDSIZE_X + 3), (FLDSIZE_Y + 2))) == NULL) 1137 return NULL; 1138 1139 /* initialize field */ 1140 memset(field, 0, FLDSIZE_X * FLDSIZE_Y * sizeof(char)); 1141 x = FLDSIZE_X / 2; 1142 y = FLDSIZE_Y / 2; 1143 1144 /* process raw key */ 1145 for (i = 0; i < dgst_raw_len; i++) { 1146 int input; 1147 /* each byte conveys four 2-bit move commands */ 1148 input = dgst_raw[i]; 1149 for (b = 0; b < 4; b++) { 1150 /* evaluate 2 bit, rest is shifted later */ 1151 x += (input & 0x1) ? 1 : -1; 1152 y += (input & 0x2) ? 1 : -1; 1153 1154 /* assure we are still in bounds */ 1155 x = MAXIMUM(x, 0); 1156 y = MAXIMUM(y, 0); 1157 x = MINIMUM(x, FLDSIZE_X - 1); 1158 y = MINIMUM(y, FLDSIZE_Y - 1); 1159 1160 /* augment the field */ 1161 if (field[x][y] < len - 2) 1162 field[x][y]++; 1163 input = input >> 2; 1164 } 1165 } 1166 1167 /* mark starting point and end point*/ 1168 field[FLDSIZE_X / 2][FLDSIZE_Y / 2] = len - 1; 1169 field[x][y] = len; 1170 1171 /* assemble title */ 1172 r = snprintf(title, sizeof(title), "[%s %u]", 1173 sshkey_type(k), sshkey_size(k)); 1174 /* If [type size] won't fit, then try [type]; fits "[ED25519-CERT]" */ 1175 if (r < 0 || r > (int)sizeof(title)) 1176 r = snprintf(title, sizeof(title), "[%s]", sshkey_type(k)); 1177 tlen = (r <= 0) ? 0 : strlen(title); 1178 1179 /* assemble hash ID. */ 1180 r = snprintf(hash, sizeof(hash), "[%s]", alg); 1181 hlen = (r <= 0) ? 0 : strlen(hash); 1182 1183 /* output upper border */ 1184 p = retval; 1185 *p++ = '+'; 1186 for (i = 0; i < (FLDSIZE_X - tlen) / 2; i++) 1187 *p++ = '-'; 1188 memcpy(p, title, tlen); 1189 p += tlen; 1190 for (i += tlen; i < FLDSIZE_X; i++) 1191 *p++ = '-'; 1192 *p++ = '+'; 1193 *p++ = '\n'; 1194 1195 /* output content */ 1196 for (y = 0; y < FLDSIZE_Y; y++) { 1197 *p++ = '|'; 1198 for (x = 0; x < FLDSIZE_X; x++) 1199 *p++ = augmentation_string[MINIMUM(field[x][y], len)]; 1200 *p++ = '|'; 1201 *p++ = '\n'; 1202 } 1203 1204 /* output lower border */ 1205 *p++ = '+'; 1206 for (i = 0; i < (FLDSIZE_X - hlen) / 2; i++) 1207 *p++ = '-'; 1208 memcpy(p, hash, hlen); 1209 p += hlen; 1210 for (i += hlen; i < FLDSIZE_X; i++) 1211 *p++ = '-'; 1212 *p++ = '+'; 1213 1214 return retval; 1215 } 1216 1217 char * 1218 sshkey_fingerprint(const struct sshkey *k, int dgst_alg, 1219 enum sshkey_fp_rep dgst_rep) 1220 { 1221 char *retval = NULL; 1222 u_char *dgst_raw; 1223 size_t dgst_raw_len; 1224 1225 if (sshkey_fingerprint_raw(k, dgst_alg, &dgst_raw, &dgst_raw_len) != 0) 1226 return NULL; 1227 switch (dgst_rep) { 1228 case SSH_FP_DEFAULT: 1229 if (dgst_alg == SSH_DIGEST_MD5) { 1230 retval = fingerprint_hex(ssh_digest_alg_name(dgst_alg), 1231 dgst_raw, dgst_raw_len); 1232 } else { 1233 retval = fingerprint_b64(ssh_digest_alg_name(dgst_alg), 1234 dgst_raw, dgst_raw_len); 1235 } 1236 break; 1237 case SSH_FP_HEX: 1238 retval = fingerprint_hex(ssh_digest_alg_name(dgst_alg), 1239 dgst_raw, dgst_raw_len); 1240 break; 1241 case SSH_FP_BASE64: 1242 retval = fingerprint_b64(ssh_digest_alg_name(dgst_alg), 1243 dgst_raw, dgst_raw_len); 1244 break; 1245 case SSH_FP_BUBBLEBABBLE: 1246 retval = fingerprint_bubblebabble(dgst_raw, dgst_raw_len); 1247 break; 1248 case SSH_FP_RANDOMART: 1249 retval = fingerprint_randomart(ssh_digest_alg_name(dgst_alg), 1250 dgst_raw, dgst_raw_len, k); 1251 break; 1252 default: 1253 freezero(dgst_raw, dgst_raw_len); 1254 return NULL; 1255 } 1256 freezero(dgst_raw, dgst_raw_len); 1257 return retval; 1258 } 1259 1260 static int 1261 peek_type_nid(const char *s, size_t l, int *nid) 1262 { 1263 const struct sshkey_impl *impl; 1264 int i; 1265 1266 for (i = 0; keyimpls[i] != NULL; i++) { 1267 impl = keyimpls[i]; 1268 if (impl->name == NULL || strlen(impl->name) != l) 1269 continue; 1270 if (memcmp(s, impl->name, l) == 0) { 1271 *nid = -1; 1272 if (key_type_is_ecdsa_variant(impl->type)) 1273 *nid = impl->nid; 1274 return impl->type; 1275 } 1276 } 1277 return KEY_UNSPEC; 1278 } 1279 1280 /* XXX this can now be made const char * */ 1281 int 1282 sshkey_read(struct sshkey *ret, char **cpp) 1283 { 1284 struct sshkey *k; 1285 char *cp, *blobcopy; 1286 size_t space; 1287 int r, type, curve_nid = -1; 1288 struct sshbuf *blob; 1289 1290 if (ret == NULL) 1291 return SSH_ERR_INVALID_ARGUMENT; 1292 if (ret->type != KEY_UNSPEC && sshkey_impl_from_type(ret->type) == NULL) 1293 return SSH_ERR_INVALID_ARGUMENT; 1294 1295 /* Decode type */ 1296 cp = *cpp; 1297 space = strcspn(cp, " \t"); 1298 if (space == strlen(cp)) 1299 return SSH_ERR_INVALID_FORMAT; 1300 if ((type = peek_type_nid(cp, space, &curve_nid)) == KEY_UNSPEC) 1301 return SSH_ERR_INVALID_FORMAT; 1302 1303 /* skip whitespace */ 1304 for (cp += space; *cp == ' ' || *cp == '\t'; cp++) 1305 ; 1306 if (*cp == '\0') 1307 return SSH_ERR_INVALID_FORMAT; 1308 if (ret->type != KEY_UNSPEC && ret->type != type) 1309 return SSH_ERR_KEY_TYPE_MISMATCH; 1310 if ((blob = sshbuf_new()) == NULL) 1311 return SSH_ERR_ALLOC_FAIL; 1312 1313 /* find end of keyblob and decode */ 1314 space = strcspn(cp, " \t"); 1315 if ((blobcopy = strndup(cp, space)) == NULL) { 1316 sshbuf_free(blob); 1317 return SSH_ERR_ALLOC_FAIL; 1318 } 1319 if ((r = sshbuf_b64tod(blob, blobcopy)) != 0) { 1320 free(blobcopy); 1321 sshbuf_free(blob); 1322 return r; 1323 } 1324 free(blobcopy); 1325 if ((r = sshkey_fromb(blob, &k)) != 0) { 1326 sshbuf_free(blob); 1327 return r; 1328 } 1329 sshbuf_free(blob); 1330 1331 /* skip whitespace and leave cp at start of comment */ 1332 for (cp += space; *cp == ' ' || *cp == '\t'; cp++) 1333 ; 1334 1335 /* ensure type of blob matches type at start of line */ 1336 if (k->type != type) { 1337 sshkey_free(k); 1338 return SSH_ERR_KEY_TYPE_MISMATCH; 1339 } 1340 if (key_type_is_ecdsa_variant(type) && curve_nid != k->ecdsa_nid) { 1341 sshkey_free(k); 1342 return SSH_ERR_EC_CURVE_MISMATCH; 1343 } 1344 1345 /* Fill in ret from parsed key */ 1346 sshkey_free_contents(ret); 1347 *ret = *k; 1348 freezero(k, sizeof(*k)); 1349 1350 /* success */ 1351 *cpp = cp; 1352 return 0; 1353 } 1354 1355 int 1356 sshkey_to_base64(const struct sshkey *key, char **b64p) 1357 { 1358 int r = SSH_ERR_INTERNAL_ERROR; 1359 struct sshbuf *b = NULL; 1360 char *uu = NULL; 1361 1362 if (b64p != NULL) 1363 *b64p = NULL; 1364 if ((b = sshbuf_new()) == NULL) 1365 return SSH_ERR_ALLOC_FAIL; 1366 if ((r = sshkey_putb(key, b)) != 0) 1367 goto out; 1368 if ((uu = sshbuf_dtob64_string(b, 0)) == NULL) { 1369 r = SSH_ERR_ALLOC_FAIL; 1370 goto out; 1371 } 1372 /* Success */ 1373 if (b64p != NULL) { 1374 *b64p = uu; 1375 uu = NULL; 1376 } 1377 r = 0; 1378 out: 1379 sshbuf_free(b); 1380 free(uu); 1381 return r; 1382 } 1383 1384 int 1385 sshkey_format_text(const struct sshkey *key, struct sshbuf *b) 1386 { 1387 int r = SSH_ERR_INTERNAL_ERROR; 1388 char *uu = NULL; 1389 1390 if ((r = sshkey_to_base64(key, &uu)) != 0) 1391 goto out; 1392 if ((r = sshbuf_putf(b, "%s %s", 1393 sshkey_ssh_name(key), uu)) != 0) 1394 goto out; 1395 r = 0; 1396 out: 1397 free(uu); 1398 return r; 1399 } 1400 1401 int 1402 sshkey_write(const struct sshkey *key, FILE *f) 1403 { 1404 struct sshbuf *b = NULL; 1405 int r = SSH_ERR_INTERNAL_ERROR; 1406 1407 if ((b = sshbuf_new()) == NULL) 1408 return SSH_ERR_ALLOC_FAIL; 1409 if ((r = sshkey_format_text(key, b)) != 0) 1410 goto out; 1411 if (fwrite(sshbuf_ptr(b), sshbuf_len(b), 1, f) != 1) { 1412 if (feof(f)) 1413 errno = EPIPE; 1414 r = SSH_ERR_SYSTEM_ERROR; 1415 goto out; 1416 } 1417 /* Success */ 1418 r = 0; 1419 out: 1420 sshbuf_free(b); 1421 return r; 1422 } 1423 1424 const char * 1425 sshkey_cert_type(const struct sshkey *k) 1426 { 1427 switch (k->cert->type) { 1428 case SSH2_CERT_TYPE_USER: 1429 return "user"; 1430 case SSH2_CERT_TYPE_HOST: 1431 return "host"; 1432 default: 1433 return "unknown"; 1434 } 1435 } 1436 1437 int 1438 sshkey_check_rsa_length(const struct sshkey *k, int min_size) 1439 { 1440 #ifdef WITH_OPENSSL 1441 int nbits; 1442 1443 if (k == NULL || k->pkey == NULL || 1444 (k->type != KEY_RSA && k->type != KEY_RSA_CERT)) 1445 return 0; 1446 nbits = EVP_PKEY_bits(k->pkey); 1447 if (nbits < SSH_RSA_MINIMUM_MODULUS_SIZE || 1448 (min_size > 0 && nbits < min_size)) 1449 return SSH_ERR_KEY_LENGTH; 1450 #endif /* WITH_OPENSSL */ 1451 return 0; 1452 } 1453 1454 #ifdef WITH_OPENSSL 1455 int 1456 sshkey_ecdsa_key_to_nid(const EC_KEY *k) 1457 { 1458 const EC_GROUP *g; 1459 int nid; 1460 1461 if (k == NULL || (g = EC_KEY_get0_group(k)) == NULL) 1462 return -1; 1463 if ((nid = EC_GROUP_get_curve_name(g)) <= 0) 1464 return -1; 1465 return nid; 1466 } 1467 1468 int 1469 sshkey_ecdsa_pkey_to_nid(EVP_PKEY *pkey) 1470 { 1471 return sshkey_ecdsa_key_to_nid(EVP_PKEY_get0_EC_KEY(pkey)); 1472 } 1473 #endif /* WITH_OPENSSL */ 1474 1475 int 1476 sshkey_generate(int type, u_int bits, struct sshkey **keyp) 1477 { 1478 struct sshkey *k; 1479 int ret = SSH_ERR_INTERNAL_ERROR; 1480 const struct sshkey_impl *impl; 1481 1482 if (keyp == NULL || sshkey_type_is_cert(type)) 1483 return SSH_ERR_INVALID_ARGUMENT; 1484 *keyp = NULL; 1485 if ((impl = sshkey_impl_from_type(type)) == NULL) 1486 return SSH_ERR_KEY_TYPE_UNKNOWN; 1487 if (impl->funcs->generate == NULL) 1488 return SSH_ERR_FEATURE_UNSUPPORTED; 1489 if ((k = sshkey_new(KEY_UNSPEC)) == NULL) 1490 return SSH_ERR_ALLOC_FAIL; 1491 k->type = type; 1492 if ((ret = impl->funcs->generate(k, bits)) != 0) { 1493 sshkey_free(k); 1494 return ret; 1495 } 1496 /* success */ 1497 *keyp = k; 1498 return 0; 1499 } 1500 1501 int 1502 sshkey_cert_copy(const struct sshkey *from_key, struct sshkey *to_key) 1503 { 1504 u_int i; 1505 const struct sshkey_cert *from; 1506 struct sshkey_cert *to; 1507 int r = SSH_ERR_INTERNAL_ERROR; 1508 1509 if (to_key == NULL || (from = from_key->cert) == NULL) 1510 return SSH_ERR_INVALID_ARGUMENT; 1511 1512 if ((to = cert_new()) == NULL) 1513 return SSH_ERR_ALLOC_FAIL; 1514 1515 if ((r = sshbuf_putb(to->certblob, from->certblob)) != 0 || 1516 (r = sshbuf_putb(to->critical, from->critical)) != 0 || 1517 (r = sshbuf_putb(to->extensions, from->extensions)) != 0) 1518 goto out; 1519 1520 to->serial = from->serial; 1521 to->type = from->type; 1522 if (from->key_id == NULL) 1523 to->key_id = NULL; 1524 else if ((to->key_id = strdup(from->key_id)) == NULL) { 1525 r = SSH_ERR_ALLOC_FAIL; 1526 goto out; 1527 } 1528 to->valid_after = from->valid_after; 1529 to->valid_before = from->valid_before; 1530 if (from->signature_key == NULL) 1531 to->signature_key = NULL; 1532 else if ((r = sshkey_from_private(from->signature_key, 1533 &to->signature_key)) != 0) 1534 goto out; 1535 if (from->signature_type != NULL && 1536 (to->signature_type = strdup(from->signature_type)) == NULL) { 1537 r = SSH_ERR_ALLOC_FAIL; 1538 goto out; 1539 } 1540 if (from->nprincipals > SSHKEY_CERT_MAX_PRINCIPALS) { 1541 r = SSH_ERR_INVALID_ARGUMENT; 1542 goto out; 1543 } 1544 if (from->nprincipals > 0) { 1545 if ((to->principals = calloc(from->nprincipals, 1546 sizeof(*to->principals))) == NULL) { 1547 r = SSH_ERR_ALLOC_FAIL; 1548 goto out; 1549 } 1550 for (i = 0; i < from->nprincipals; i++) { 1551 to->principals[i] = strdup(from->principals[i]); 1552 if (to->principals[i] == NULL) { 1553 to->nprincipals = i; 1554 r = SSH_ERR_ALLOC_FAIL; 1555 goto out; 1556 } 1557 } 1558 } 1559 to->nprincipals = from->nprincipals; 1560 1561 /* success */ 1562 cert_free(to_key->cert); 1563 to_key->cert = to; 1564 to = NULL; 1565 r = 0; 1566 out: 1567 cert_free(to); 1568 return r; 1569 } 1570 1571 int 1572 sshkey_copy_public_sk(const struct sshkey *from, struct sshkey *to) 1573 { 1574 /* Append security-key application string */ 1575 if ((to->sk_application = strdup(from->sk_application)) == NULL) 1576 return SSH_ERR_ALLOC_FAIL; 1577 return 0; 1578 } 1579 1580 int 1581 sshkey_from_private(const struct sshkey *k, struct sshkey **pkp) 1582 { 1583 struct sshkey *n = NULL; 1584 int r = SSH_ERR_INTERNAL_ERROR; 1585 const struct sshkey_impl *impl; 1586 1587 *pkp = NULL; 1588 if ((impl = sshkey_impl_from_key(k)) == NULL) 1589 return SSH_ERR_KEY_TYPE_UNKNOWN; 1590 if ((n = sshkey_new(k->type)) == NULL) { 1591 r = SSH_ERR_ALLOC_FAIL; 1592 goto out; 1593 } 1594 if ((r = impl->funcs->copy_public(k, n)) != 0) 1595 goto out; 1596 if (sshkey_is_cert(k) && (r = sshkey_cert_copy(k, n)) != 0) 1597 goto out; 1598 /* success */ 1599 *pkp = n; 1600 n = NULL; 1601 r = 0; 1602 out: 1603 sshkey_free(n); 1604 return r; 1605 } 1606 1607 int 1608 sshkey_is_shielded(struct sshkey *k) 1609 { 1610 return k != NULL && k->shielded_private != NULL; 1611 } 1612 1613 int 1614 sshkey_shield_private(struct sshkey *k) 1615 { 1616 struct sshbuf *prvbuf = NULL; 1617 u_char *prekey = NULL, *enc = NULL, keyiv[SSH_DIGEST_MAX_LENGTH]; 1618 struct sshcipher_ctx *cctx = NULL; 1619 const struct sshcipher *cipher; 1620 size_t i, enclen = 0; 1621 struct sshkey *kswap = NULL, tmp; 1622 int r = SSH_ERR_INTERNAL_ERROR; 1623 1624 #ifdef DEBUG_PK 1625 fprintf(stderr, "%s: entering for %s\n", __func__, sshkey_ssh_name(k)); 1626 #endif 1627 if ((cipher = cipher_by_name(SSHKEY_SHIELD_CIPHER)) == NULL) { 1628 r = SSH_ERR_INVALID_ARGUMENT; 1629 goto out; 1630 } 1631 if (cipher_keylen(cipher) + cipher_ivlen(cipher) > 1632 ssh_digest_bytes(SSHKEY_SHIELD_PREKEY_HASH)) { 1633 r = SSH_ERR_INTERNAL_ERROR; 1634 goto out; 1635 } 1636 1637 /* Prepare a random pre-key, and from it an ephemeral key */ 1638 if ((r = sshkey_prekey_alloc(&prekey, SSHKEY_SHIELD_PREKEY_LEN)) != 0) 1639 goto out; 1640 arc4random_buf(prekey, SSHKEY_SHIELD_PREKEY_LEN); 1641 if ((r = ssh_digest_memory(SSHKEY_SHIELD_PREKEY_HASH, 1642 prekey, SSHKEY_SHIELD_PREKEY_LEN, 1643 keyiv, SSH_DIGEST_MAX_LENGTH)) != 0) 1644 goto out; 1645 #ifdef DEBUG_PK 1646 fprintf(stderr, "%s: key+iv\n", __func__); 1647 sshbuf_dump_data(keyiv, ssh_digest_bytes(SSHKEY_SHIELD_PREKEY_HASH), 1648 stderr); 1649 #endif 1650 if ((r = cipher_init(&cctx, cipher, keyiv, cipher_keylen(cipher), 1651 keyiv + cipher_keylen(cipher), cipher_ivlen(cipher), 1)) != 0) 1652 goto out; 1653 1654 /* Serialise and encrypt the private key using the ephemeral key */ 1655 if ((prvbuf = sshbuf_new()) == NULL) { 1656 r = SSH_ERR_ALLOC_FAIL; 1657 goto out; 1658 } 1659 if (sshkey_is_shielded(k) && (r = sshkey_unshield_private(k)) != 0) 1660 goto out; 1661 if ((r = sshkey_private_serialize_opt(k, prvbuf, 1662 SSHKEY_SERIALIZE_SHIELD)) != 0) 1663 goto out; 1664 /* pad to cipher blocksize */ 1665 i = 0; 1666 while (sshbuf_len(prvbuf) % cipher_blocksize(cipher)) { 1667 if ((r = sshbuf_put_u8(prvbuf, ++i & 0xff)) != 0) 1668 goto out; 1669 } 1670 #ifdef DEBUG_PK 1671 fprintf(stderr, "%s: serialised\n", __func__); 1672 sshbuf_dump(prvbuf, stderr); 1673 #endif 1674 /* encrypt */ 1675 enclen = sshbuf_len(prvbuf); 1676 if ((enc = malloc(enclen)) == NULL) { 1677 r = SSH_ERR_ALLOC_FAIL; 1678 goto out; 1679 } 1680 if ((r = cipher_crypt(cctx, 0, enc, 1681 sshbuf_ptr(prvbuf), sshbuf_len(prvbuf), 0, 0)) != 0) 1682 goto out; 1683 #ifdef DEBUG_PK 1684 fprintf(stderr, "%s: encrypted\n", __func__); 1685 sshbuf_dump_data(enc, enclen, stderr); 1686 #endif 1687 1688 /* Make a scrubbed, public-only copy of our private key argument */ 1689 if ((r = sshkey_from_private(k, &kswap)) != 0) 1690 goto out; 1691 1692 /* Swap the private key out (it will be destroyed below) */ 1693 tmp = *kswap; 1694 *kswap = *k; 1695 *k = tmp; 1696 1697 /* Insert the shielded key into our argument */ 1698 k->shielded_private = enc; 1699 k->shielded_len = enclen; 1700 k->shield_prekey = prekey; 1701 k->shield_prekey_len = SSHKEY_SHIELD_PREKEY_LEN; 1702 enc = prekey = NULL; /* transferred */ 1703 enclen = 0; 1704 1705 /* preserve key fields that are required for correct operation */ 1706 k->sk_flags = kswap->sk_flags; 1707 1708 /* success */ 1709 r = 0; 1710 1711 out: 1712 /* XXX behaviour on error - invalidate original private key? */ 1713 cipher_free(cctx); 1714 explicit_bzero(keyiv, sizeof(keyiv)); 1715 explicit_bzero(&tmp, sizeof(tmp)); 1716 freezero(enc, enclen); 1717 sshkey_prekey_free(prekey, SSHKEY_SHIELD_PREKEY_LEN); 1718 sshkey_free(kswap); 1719 sshbuf_free(prvbuf); 1720 return r; 1721 } 1722 1723 /* Check deterministic padding after private key */ 1724 static int 1725 private2_check_padding(struct sshbuf *decrypted) 1726 { 1727 u_char pad; 1728 size_t i; 1729 int r; 1730 1731 i = 0; 1732 while (sshbuf_len(decrypted)) { 1733 if ((r = sshbuf_get_u8(decrypted, &pad)) != 0) 1734 goto out; 1735 if (pad != (++i & 0xff)) { 1736 r = SSH_ERR_INVALID_FORMAT; 1737 goto out; 1738 } 1739 } 1740 /* success */ 1741 r = 0; 1742 out: 1743 explicit_bzero(&pad, sizeof(pad)); 1744 explicit_bzero(&i, sizeof(i)); 1745 return r; 1746 } 1747 1748 int 1749 sshkey_unshield_private(struct sshkey *k) 1750 { 1751 struct sshbuf *prvbuf = NULL; 1752 u_char *cp, keyiv[SSH_DIGEST_MAX_LENGTH]; 1753 struct sshcipher_ctx *cctx = NULL; 1754 const struct sshcipher *cipher; 1755 struct sshkey *kswap = NULL, tmp; 1756 int r = SSH_ERR_INTERNAL_ERROR; 1757 1758 #ifdef DEBUG_PK 1759 fprintf(stderr, "%s: entering for %s\n", __func__, sshkey_ssh_name(k)); 1760 #endif 1761 if (!sshkey_is_shielded(k)) 1762 return 0; /* nothing to do */ 1763 1764 if ((cipher = cipher_by_name(SSHKEY_SHIELD_CIPHER)) == NULL) { 1765 r = SSH_ERR_INVALID_ARGUMENT; 1766 goto out; 1767 } 1768 if (cipher_keylen(cipher) + cipher_ivlen(cipher) > 1769 ssh_digest_bytes(SSHKEY_SHIELD_PREKEY_HASH)) { 1770 r = SSH_ERR_INTERNAL_ERROR; 1771 goto out; 1772 } 1773 /* check size of shielded key blob */ 1774 if (k->shielded_len < cipher_blocksize(cipher) || 1775 (k->shielded_len % cipher_blocksize(cipher)) != 0) { 1776 r = SSH_ERR_INVALID_FORMAT; 1777 goto out; 1778 } 1779 1780 /* Calculate the ephemeral key from the prekey */ 1781 if ((r = ssh_digest_memory(SSHKEY_SHIELD_PREKEY_HASH, 1782 k->shield_prekey, k->shield_prekey_len, 1783 keyiv, SSH_DIGEST_MAX_LENGTH)) != 0) 1784 goto out; 1785 if ((r = cipher_init(&cctx, cipher, keyiv, cipher_keylen(cipher), 1786 keyiv + cipher_keylen(cipher), cipher_ivlen(cipher), 0)) != 0) 1787 goto out; 1788 #ifdef DEBUG_PK 1789 fprintf(stderr, "%s: key+iv\n", __func__); 1790 sshbuf_dump_data(keyiv, ssh_digest_bytes(SSHKEY_SHIELD_PREKEY_HASH), 1791 stderr); 1792 #endif 1793 1794 /* Decrypt and parse the shielded private key using the ephemeral key */ 1795 if ((prvbuf = sshbuf_new()) == NULL) { 1796 r = SSH_ERR_ALLOC_FAIL; 1797 goto out; 1798 } 1799 if ((r = sshbuf_reserve(prvbuf, k->shielded_len, &cp)) != 0) 1800 goto out; 1801 /* decrypt */ 1802 #ifdef DEBUG_PK 1803 fprintf(stderr, "%s: encrypted\n", __func__); 1804 sshbuf_dump_data(k->shielded_private, k->shielded_len, stderr); 1805 #endif 1806 if ((r = cipher_crypt(cctx, 0, cp, 1807 k->shielded_private, k->shielded_len, 0, 0)) != 0) 1808 goto out; 1809 #ifdef DEBUG_PK 1810 fprintf(stderr, "%s: serialised\n", __func__); 1811 sshbuf_dump(prvbuf, stderr); 1812 #endif 1813 /* Parse private key */ 1814 if ((r = sshkey_private_deserialize(prvbuf, &kswap)) != 0) 1815 goto out; 1816 1817 if ((r = private2_check_padding(prvbuf)) != 0) 1818 goto out; 1819 1820 /* Swap the parsed key back into place */ 1821 tmp = *kswap; 1822 *kswap = *k; 1823 *k = tmp; 1824 1825 /* success */ 1826 r = 0; 1827 1828 out: 1829 cipher_free(cctx); 1830 explicit_bzero(keyiv, sizeof(keyiv)); 1831 explicit_bzero(&tmp, sizeof(tmp)); 1832 sshkey_free(kswap); 1833 sshbuf_free(prvbuf); 1834 return r; 1835 } 1836 1837 static int 1838 cert_parse(struct sshbuf *b, struct sshkey *key, struct sshbuf *certbuf) 1839 { 1840 struct sshbuf *principals = NULL, *crit = NULL; 1841 struct sshbuf *exts = NULL, *ca = NULL; 1842 u_char *sig = NULL; 1843 size_t signed_len = 0, slen = 0, kidlen = 0; 1844 int ret = SSH_ERR_INTERNAL_ERROR; 1845 1846 /* Copy the entire key blob for verification and later serialisation */ 1847 if ((ret = sshbuf_putb(key->cert->certblob, certbuf)) != 0) 1848 return ret; 1849 1850 /* Parse body of certificate up to signature */ 1851 if ((ret = sshbuf_get_u64(b, &key->cert->serial)) != 0 || 1852 (ret = sshbuf_get_u32(b, &key->cert->type)) != 0 || 1853 (ret = sshbuf_get_cstring(b, &key->cert->key_id, &kidlen)) != 0 || 1854 (ret = sshbuf_froms(b, &principals)) != 0 || 1855 (ret = sshbuf_get_u64(b, &key->cert->valid_after)) != 0 || 1856 (ret = sshbuf_get_u64(b, &key->cert->valid_before)) != 0 || 1857 (ret = sshbuf_froms(b, &crit)) != 0 || 1858 (ret = sshbuf_froms(b, &exts)) != 0 || 1859 (ret = sshbuf_get_string_direct(b, NULL, NULL)) != 0 || 1860 (ret = sshbuf_froms(b, &ca)) != 0) { 1861 /* XXX debug print error for ret */ 1862 ret = SSH_ERR_INVALID_FORMAT; 1863 goto out; 1864 } 1865 1866 /* Signature is left in the buffer so we can calculate this length */ 1867 signed_len = sshbuf_len(key->cert->certblob) - sshbuf_len(b); 1868 1869 if ((ret = sshbuf_get_string(b, &sig, &slen)) != 0) { 1870 ret = SSH_ERR_INVALID_FORMAT; 1871 goto out; 1872 } 1873 1874 if (key->cert->type != SSH2_CERT_TYPE_USER && 1875 key->cert->type != SSH2_CERT_TYPE_HOST) { 1876 ret = SSH_ERR_KEY_CERT_UNKNOWN_TYPE; 1877 goto out; 1878 } 1879 1880 /* Parse principals section */ 1881 while (sshbuf_len(principals) > 0) { 1882 char *principal = NULL; 1883 char **oprincipals = NULL; 1884 1885 if (key->cert->nprincipals >= SSHKEY_CERT_MAX_PRINCIPALS) { 1886 ret = SSH_ERR_INVALID_FORMAT; 1887 goto out; 1888 } 1889 if ((ret = sshbuf_get_cstring(principals, &principal, 1890 NULL)) != 0) { 1891 ret = SSH_ERR_INVALID_FORMAT; 1892 goto out; 1893 } 1894 oprincipals = key->cert->principals; 1895 key->cert->principals = recallocarray(key->cert->principals, 1896 key->cert->nprincipals, key->cert->nprincipals + 1, 1897 sizeof(*key->cert->principals)); 1898 if (key->cert->principals == NULL) { 1899 free(principal); 1900 key->cert->principals = oprincipals; 1901 ret = SSH_ERR_ALLOC_FAIL; 1902 goto out; 1903 } 1904 key->cert->principals[key->cert->nprincipals++] = principal; 1905 } 1906 1907 /* 1908 * Stash a copies of the critical options and extensions sections 1909 * for later use. 1910 */ 1911 if ((ret = sshbuf_putb(key->cert->critical, crit)) != 0 || 1912 (exts != NULL && 1913 (ret = sshbuf_putb(key->cert->extensions, exts)) != 0)) 1914 goto out; 1915 1916 /* 1917 * Validate critical options and extensions sections format. 1918 */ 1919 while (sshbuf_len(crit) != 0) { 1920 if ((ret = sshbuf_get_string_direct(crit, NULL, NULL)) != 0 || 1921 (ret = sshbuf_get_string_direct(crit, NULL, NULL)) != 0) { 1922 sshbuf_reset(key->cert->critical); 1923 ret = SSH_ERR_INVALID_FORMAT; 1924 goto out; 1925 } 1926 } 1927 while (exts != NULL && sshbuf_len(exts) != 0) { 1928 if ((ret = sshbuf_get_string_direct(exts, NULL, NULL)) != 0 || 1929 (ret = sshbuf_get_string_direct(exts, NULL, NULL)) != 0) { 1930 sshbuf_reset(key->cert->extensions); 1931 ret = SSH_ERR_INVALID_FORMAT; 1932 goto out; 1933 } 1934 } 1935 1936 /* Parse CA key and check signature */ 1937 if (sshkey_from_blob_internal(ca, &key->cert->signature_key, 0) != 0) { 1938 ret = SSH_ERR_KEY_CERT_INVALID_SIGN_KEY; 1939 goto out; 1940 } 1941 if (!sshkey_type_is_valid_ca(key->cert->signature_key->type)) { 1942 ret = SSH_ERR_KEY_CERT_INVALID_SIGN_KEY; 1943 goto out; 1944 } 1945 if ((ret = sshkey_verify(key->cert->signature_key, sig, slen, 1946 sshbuf_ptr(key->cert->certblob), signed_len, NULL, 0, NULL)) != 0) 1947 goto out; 1948 if ((ret = sshkey_get_sigtype(sig, slen, 1949 &key->cert->signature_type)) != 0) 1950 goto out; 1951 1952 /* Success */ 1953 ret = 0; 1954 out: 1955 sshbuf_free(ca); 1956 sshbuf_free(crit); 1957 sshbuf_free(exts); 1958 sshbuf_free(principals); 1959 free(sig); 1960 return ret; 1961 } 1962 1963 int 1964 sshkey_deserialize_sk(struct sshbuf *b, struct sshkey *key) 1965 { 1966 /* Parse additional security-key application string */ 1967 if (sshbuf_get_cstring(b, &key->sk_application, NULL) != 0) 1968 return SSH_ERR_INVALID_FORMAT; 1969 return 0; 1970 } 1971 1972 static int 1973 sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp, 1974 int allow_cert) 1975 { 1976 int type, ret = SSH_ERR_INTERNAL_ERROR; 1977 char *ktype = NULL; 1978 struct sshkey *key = NULL; 1979 struct sshbuf *copy; 1980 const struct sshkey_impl *impl; 1981 1982 #ifdef DEBUG_PK /* XXX */ 1983 sshbuf_dump(b, stderr); 1984 #endif 1985 if (keyp != NULL) 1986 *keyp = NULL; 1987 if ((copy = sshbuf_fromb(b)) == NULL) { 1988 ret = SSH_ERR_ALLOC_FAIL; 1989 goto out; 1990 } 1991 if (sshbuf_get_cstring(b, &ktype, NULL) != 0) { 1992 ret = SSH_ERR_INVALID_FORMAT; 1993 goto out; 1994 } 1995 1996 type = sshkey_type_from_name(ktype); 1997 if (!allow_cert && sshkey_type_is_cert(type)) { 1998 ret = SSH_ERR_KEY_CERT_INVALID_SIGN_KEY; 1999 goto out; 2000 } 2001 if ((impl = sshkey_impl_from_type(type)) == NULL) { 2002 ret = SSH_ERR_KEY_TYPE_UNKNOWN; 2003 goto out; 2004 } 2005 if ((key = sshkey_new(type)) == NULL) { 2006 ret = SSH_ERR_ALLOC_FAIL; 2007 goto out; 2008 } 2009 if (sshkey_type_is_cert(type)) { 2010 /* Skip nonce that precedes all certificates */ 2011 if (sshbuf_get_string_direct(b, NULL, NULL) != 0) { 2012 ret = SSH_ERR_INVALID_FORMAT; 2013 goto out; 2014 } 2015 } 2016 if ((ret = impl->funcs->deserialize_public(ktype, b, key)) != 0) 2017 goto out; 2018 2019 /* Parse certificate potion */ 2020 if (sshkey_is_cert(key) && (ret = cert_parse(b, key, copy)) != 0) 2021 goto out; 2022 2023 if (key != NULL && sshbuf_len(b) != 0) { 2024 ret = SSH_ERR_INVALID_FORMAT; 2025 goto out; 2026 } 2027 ret = 0; 2028 if (keyp != NULL) { 2029 *keyp = key; 2030 key = NULL; 2031 } 2032 out: 2033 sshbuf_free(copy); 2034 sshkey_free(key); 2035 free(ktype); 2036 return ret; 2037 } 2038 2039 int 2040 sshkey_from_blob(const u_char *blob, size_t blen, struct sshkey **keyp) 2041 { 2042 struct sshbuf *b; 2043 int r; 2044 2045 if ((b = sshbuf_from(blob, blen)) == NULL) 2046 return SSH_ERR_ALLOC_FAIL; 2047 r = sshkey_from_blob_internal(b, keyp, 1); 2048 sshbuf_free(b); 2049 return r; 2050 } 2051 2052 int 2053 sshkey_fromb(struct sshbuf *b, struct sshkey **keyp) 2054 { 2055 return sshkey_from_blob_internal(b, keyp, 1); 2056 } 2057 2058 int 2059 sshkey_froms(struct sshbuf *buf, struct sshkey **keyp) 2060 { 2061 struct sshbuf *b; 2062 int r; 2063 2064 if ((r = sshbuf_froms(buf, &b)) != 0) 2065 return r; 2066 r = sshkey_from_blob_internal(b, keyp, 1); 2067 sshbuf_free(b); 2068 return r; 2069 } 2070 2071 int 2072 sshkey_get_sigtype(const u_char *sig, size_t siglen, char **sigtypep) 2073 { 2074 int r; 2075 struct sshbuf *b = NULL; 2076 char *sigtype = NULL; 2077 2078 if (sigtypep != NULL) 2079 *sigtypep = NULL; 2080 if ((b = sshbuf_from(sig, siglen)) == NULL) 2081 return SSH_ERR_ALLOC_FAIL; 2082 if ((r = sshbuf_get_cstring(b, &sigtype, NULL)) != 0) 2083 goto out; 2084 /* success */ 2085 if (sigtypep != NULL) { 2086 *sigtypep = sigtype; 2087 sigtype = NULL; 2088 } 2089 r = 0; 2090 out: 2091 free(sigtype); 2092 sshbuf_free(b); 2093 return r; 2094 } 2095 2096 /* 2097 * 2098 * Checks whether a certificate's signature type is allowed. 2099 * Returns 0 (success) if the certificate signature type appears in the 2100 * "allowed" pattern-list, or the key is not a certificate to begin with. 2101 * Otherwise returns a ssherr.h code. 2102 */ 2103 int 2104 sshkey_check_cert_sigtype(const struct sshkey *key, const char *allowed) 2105 { 2106 if (key == NULL || allowed == NULL) 2107 return SSH_ERR_INVALID_ARGUMENT; 2108 if (!sshkey_type_is_cert(key->type)) 2109 return 0; 2110 if (key->cert == NULL || key->cert->signature_type == NULL) 2111 return SSH_ERR_INVALID_ARGUMENT; 2112 if (match_pattern_list(key->cert->signature_type, allowed, 0) != 1) 2113 return SSH_ERR_SIGN_ALG_UNSUPPORTED; 2114 return 0; 2115 } 2116 2117 /* 2118 * Returns the expected signature algorithm for a given public key algorithm. 2119 */ 2120 const char * 2121 sshkey_sigalg_by_name(const char *name) 2122 { 2123 const struct sshkey_impl *impl; 2124 int i; 2125 2126 for (i = 0; keyimpls[i] != NULL; i++) { 2127 impl = keyimpls[i]; 2128 if (strcmp(impl->name, name) != 0) 2129 continue; 2130 if (impl->sigalg != NULL) 2131 return impl->sigalg; 2132 if (!impl->cert) 2133 return impl->name; 2134 return sshkey_ssh_name_from_type_nid( 2135 sshkey_type_plain(impl->type), impl->nid); 2136 } 2137 return NULL; 2138 } 2139 2140 /* 2141 * Verifies that the signature algorithm appearing inside the signature blob 2142 * matches that which was requested. 2143 */ 2144 int 2145 sshkey_check_sigtype(const u_char *sig, size_t siglen, 2146 const char *requested_alg) 2147 { 2148 const char *expected_alg; 2149 char *sigtype = NULL; 2150 int r; 2151 2152 if (requested_alg == NULL) 2153 return 0; 2154 if ((expected_alg = sshkey_sigalg_by_name(requested_alg)) == NULL) 2155 return SSH_ERR_INVALID_ARGUMENT; 2156 if ((r = sshkey_get_sigtype(sig, siglen, &sigtype)) != 0) 2157 return r; 2158 r = strcmp(expected_alg, sigtype) == 0; 2159 free(sigtype); 2160 return r ? 0 : SSH_ERR_SIGN_ALG_UNSUPPORTED; 2161 } 2162 2163 int 2164 sshkey_sign(struct sshkey *key, 2165 u_char **sigp, size_t *lenp, 2166 const u_char *data, size_t datalen, 2167 const char *alg, const char *sk_provider, const char *sk_pin, u_int compat) 2168 { 2169 int was_shielded = sshkey_is_shielded(key); 2170 int r2, r = SSH_ERR_INTERNAL_ERROR; 2171 const struct sshkey_impl *impl; 2172 2173 if (sigp != NULL) 2174 *sigp = NULL; 2175 if (lenp != NULL) 2176 *lenp = 0; 2177 if (datalen > SSH_KEY_MAX_SIGN_DATA_SIZE) 2178 return SSH_ERR_INVALID_ARGUMENT; 2179 if ((impl = sshkey_impl_from_key(key)) == NULL) 2180 return SSH_ERR_KEY_TYPE_UNKNOWN; 2181 if ((r = sshkey_unshield_private(key)) != 0) 2182 return r; 2183 if (sshkey_is_sk(key)) { 2184 r = sshsk_sign(sk_provider, key, sigp, lenp, data, 2185 datalen, compat, sk_pin); 2186 } else { 2187 if (impl->funcs->sign == NULL) 2188 r = SSH_ERR_SIGN_ALG_UNSUPPORTED; 2189 else { 2190 r = impl->funcs->sign(key, sigp, lenp, data, datalen, 2191 alg, sk_provider, sk_pin, compat); 2192 } 2193 } 2194 if (was_shielded && (r2 = sshkey_shield_private(key)) != 0) 2195 return r2; 2196 return r; 2197 } 2198 2199 /* 2200 * ssh_key_verify returns 0 for a correct signature and < 0 on error. 2201 * If "alg" specified, then the signature must use that algorithm. 2202 */ 2203 int 2204 sshkey_verify(const struct sshkey *key, 2205 const u_char *sig, size_t siglen, 2206 const u_char *data, size_t dlen, const char *alg, u_int compat, 2207 struct sshkey_sig_details **detailsp) 2208 { 2209 const struct sshkey_impl *impl; 2210 2211 if (detailsp != NULL) 2212 *detailsp = NULL; 2213 if (siglen == 0 || dlen > SSH_KEY_MAX_SIGN_DATA_SIZE) 2214 return SSH_ERR_INVALID_ARGUMENT; 2215 if ((impl = sshkey_impl_from_key(key)) == NULL) 2216 return SSH_ERR_KEY_TYPE_UNKNOWN; 2217 return impl->funcs->verify(key, sig, siglen, data, dlen, 2218 alg, compat, detailsp); 2219 } 2220 2221 /* Convert a plain key to their _CERT equivalent */ 2222 int 2223 sshkey_to_certified(struct sshkey *k) 2224 { 2225 int newtype; 2226 2227 if ((newtype = sshkey_type_certified(k->type)) == -1) 2228 return SSH_ERR_INVALID_ARGUMENT; 2229 if ((k->cert = cert_new()) == NULL) 2230 return SSH_ERR_ALLOC_FAIL; 2231 k->type = newtype; 2232 return 0; 2233 } 2234 2235 /* Convert a certificate to its raw key equivalent */ 2236 int 2237 sshkey_drop_cert(struct sshkey *k) 2238 { 2239 if (!sshkey_type_is_cert(k->type)) 2240 return SSH_ERR_KEY_TYPE_UNKNOWN; 2241 cert_free(k->cert); 2242 k->cert = NULL; 2243 k->type = sshkey_type_plain(k->type); 2244 return 0; 2245 } 2246 2247 /* Sign a certified key, (re-)generating the signed certblob. */ 2248 int 2249 sshkey_certify_custom(struct sshkey *k, struct sshkey *ca, const char *alg, 2250 const char *sk_provider, const char *sk_pin, 2251 sshkey_certify_signer *signer, void *signer_ctx) 2252 { 2253 const struct sshkey_impl *impl; 2254 struct sshbuf *principals = NULL; 2255 u_char *ca_blob = NULL, *sig_blob = NULL, nonce[32]; 2256 size_t i, ca_len, sig_len; 2257 int ret = SSH_ERR_INTERNAL_ERROR; 2258 struct sshbuf *cert = NULL; 2259 char *sigtype = NULL; 2260 2261 if (k == NULL || k->cert == NULL || 2262 k->cert->certblob == NULL || ca == NULL) 2263 return SSH_ERR_INVALID_ARGUMENT; 2264 if (!sshkey_is_cert(k)) 2265 return SSH_ERR_KEY_TYPE_UNKNOWN; 2266 if (!sshkey_type_is_valid_ca(ca->type)) 2267 return SSH_ERR_KEY_CERT_INVALID_SIGN_KEY; 2268 if ((impl = sshkey_impl_from_key(k)) == NULL) 2269 return SSH_ERR_INTERNAL_ERROR; 2270 2271 /* 2272 * If no alg specified as argument but a signature_type was set, 2273 * then prefer that. If both were specified, then they must match. 2274 */ 2275 if (alg == NULL) 2276 alg = k->cert->signature_type; 2277 else if (k->cert->signature_type != NULL && 2278 strcmp(alg, k->cert->signature_type) != 0) 2279 return SSH_ERR_INVALID_ARGUMENT; 2280 2281 /* 2282 * If no signing algorithm or signature_type was specified and we're 2283 * using a RSA key, then default to a good signature algorithm. 2284 */ 2285 if (alg == NULL && ca->type == KEY_RSA) 2286 alg = "rsa-sha2-512"; 2287 2288 if ((ret = sshkey_to_blob(ca, &ca_blob, &ca_len)) != 0) 2289 return SSH_ERR_KEY_CERT_INVALID_SIGN_KEY; 2290 2291 cert = k->cert->certblob; /* for readability */ 2292 sshbuf_reset(cert); 2293 if ((ret = sshbuf_put_cstring(cert, sshkey_ssh_name(k))) != 0) 2294 goto out; 2295 2296 /* -v01 certs put nonce first */ 2297 arc4random_buf(&nonce, sizeof(nonce)); 2298 if ((ret = sshbuf_put_string(cert, nonce, sizeof(nonce))) != 0) 2299 goto out; 2300 2301 /* Public key next */ 2302 if ((ret = impl->funcs->serialize_public(k, cert, 2303 SSHKEY_SERIALIZE_DEFAULT)) != 0) 2304 goto out; 2305 2306 /* Then remaining cert fields */ 2307 if ((ret = sshbuf_put_u64(cert, k->cert->serial)) != 0 || 2308 (ret = sshbuf_put_u32(cert, k->cert->type)) != 0 || 2309 (ret = sshbuf_put_cstring(cert, k->cert->key_id)) != 0) 2310 goto out; 2311 2312 if ((principals = sshbuf_new()) == NULL) { 2313 ret = SSH_ERR_ALLOC_FAIL; 2314 goto out; 2315 } 2316 for (i = 0; i < k->cert->nprincipals; i++) { 2317 if ((ret = sshbuf_put_cstring(principals, 2318 k->cert->principals[i])) != 0) 2319 goto out; 2320 } 2321 if ((ret = sshbuf_put_stringb(cert, principals)) != 0 || 2322 (ret = sshbuf_put_u64(cert, k->cert->valid_after)) != 0 || 2323 (ret = sshbuf_put_u64(cert, k->cert->valid_before)) != 0 || 2324 (ret = sshbuf_put_stringb(cert, k->cert->critical)) != 0 || 2325 (ret = sshbuf_put_stringb(cert, k->cert->extensions)) != 0 || 2326 (ret = sshbuf_put_string(cert, NULL, 0)) != 0 || /* Reserved */ 2327 (ret = sshbuf_put_string(cert, ca_blob, ca_len)) != 0) 2328 goto out; 2329 2330 /* Sign the whole mess */ 2331 if ((ret = signer(ca, &sig_blob, &sig_len, sshbuf_ptr(cert), 2332 sshbuf_len(cert), alg, sk_provider, sk_pin, 0, signer_ctx)) != 0) 2333 goto out; 2334 /* Check and update signature_type against what was actually used */ 2335 if ((ret = sshkey_get_sigtype(sig_blob, sig_len, &sigtype)) != 0) 2336 goto out; 2337 if (alg != NULL && strcmp(alg, sigtype) != 0) { 2338 ret = SSH_ERR_SIGN_ALG_UNSUPPORTED; 2339 goto out; 2340 } 2341 if (k->cert->signature_type == NULL) { 2342 k->cert->signature_type = sigtype; 2343 sigtype = NULL; 2344 } 2345 /* Append signature and we are done */ 2346 if ((ret = sshbuf_put_string(cert, sig_blob, sig_len)) != 0) 2347 goto out; 2348 ret = 0; 2349 out: 2350 if (ret != 0) 2351 sshbuf_reset(cert); 2352 free(sig_blob); 2353 free(ca_blob); 2354 free(sigtype); 2355 sshbuf_free(principals); 2356 return ret; 2357 } 2358 2359 static int 2360 default_key_sign(struct sshkey *key, u_char **sigp, size_t *lenp, 2361 const u_char *data, size_t datalen, 2362 const char *alg, const char *sk_provider, const char *sk_pin, 2363 u_int compat, void *ctx) 2364 { 2365 if (ctx != NULL) 2366 return SSH_ERR_INVALID_ARGUMENT; 2367 return sshkey_sign(key, sigp, lenp, data, datalen, alg, 2368 sk_provider, sk_pin, compat); 2369 } 2370 2371 int 2372 sshkey_certify(struct sshkey *k, struct sshkey *ca, const char *alg, 2373 const char *sk_provider, const char *sk_pin) 2374 { 2375 return sshkey_certify_custom(k, ca, alg, sk_provider, sk_pin, 2376 default_key_sign, NULL); 2377 } 2378 2379 int 2380 sshkey_cert_check_authority(const struct sshkey *k, 2381 int want_host, int require_principal, int wildcard_pattern, 2382 uint64_t verify_time, const char *name, const char **reason) 2383 { 2384 u_int i, principal_matches; 2385 2386 if (reason == NULL) 2387 return SSH_ERR_INVALID_ARGUMENT; 2388 if (!sshkey_is_cert(k)) { 2389 *reason = "Key is not a certificate"; 2390 return SSH_ERR_KEY_CERT_INVALID; 2391 } 2392 if (want_host) { 2393 if (k->cert->type != SSH2_CERT_TYPE_HOST) { 2394 *reason = "Certificate invalid: not a host certificate"; 2395 return SSH_ERR_KEY_CERT_INVALID; 2396 } 2397 } else { 2398 if (k->cert->type != SSH2_CERT_TYPE_USER) { 2399 *reason = "Certificate invalid: not a user certificate"; 2400 return SSH_ERR_KEY_CERT_INVALID; 2401 } 2402 } 2403 if (verify_time < k->cert->valid_after) { 2404 *reason = "Certificate invalid: not yet valid"; 2405 return SSH_ERR_KEY_CERT_INVALID; 2406 } 2407 if (verify_time >= k->cert->valid_before) { 2408 *reason = "Certificate invalid: expired"; 2409 return SSH_ERR_KEY_CERT_INVALID; 2410 } 2411 if (k->cert->nprincipals == 0) { 2412 if (require_principal) { 2413 *reason = "Certificate lacks principal list"; 2414 return SSH_ERR_KEY_CERT_INVALID; 2415 } 2416 } else if (name != NULL) { 2417 principal_matches = 0; 2418 for (i = 0; i < k->cert->nprincipals; i++) { 2419 if (wildcard_pattern) { 2420 if (match_pattern(k->cert->principals[i], 2421 name)) { 2422 principal_matches = 1; 2423 break; 2424 } 2425 } else if (strcmp(name, k->cert->principals[i]) == 0) { 2426 principal_matches = 1; 2427 break; 2428 } 2429 } 2430 if (!principal_matches) { 2431 *reason = "Certificate invalid: name is not a listed " 2432 "principal"; 2433 return SSH_ERR_KEY_CERT_INVALID; 2434 } 2435 } 2436 return 0; 2437 } 2438 2439 int 2440 sshkey_cert_check_authority_now(const struct sshkey *k, 2441 int want_host, int require_principal, int wildcard_pattern, 2442 const char *name, const char **reason) 2443 { 2444 time_t now; 2445 2446 if ((now = time(NULL)) < 0) { 2447 /* yikes - system clock before epoch! */ 2448 *reason = "Certificate invalid: not yet valid"; 2449 return SSH_ERR_KEY_CERT_INVALID; 2450 } 2451 return sshkey_cert_check_authority(k, want_host, require_principal, 2452 wildcard_pattern, (uint64_t)now, name, reason); 2453 } 2454 2455 int 2456 sshkey_cert_check_host(const struct sshkey *key, const char *host, 2457 int wildcard_principals, const char *ca_sign_algorithms, 2458 const char **reason) 2459 { 2460 int r; 2461 2462 if ((r = sshkey_cert_check_authority_now(key, 1, 0, wildcard_principals, 2463 host, reason)) != 0) 2464 return r; 2465 if (sshbuf_len(key->cert->critical) != 0) { 2466 *reason = "Certificate contains unsupported critical options"; 2467 return SSH_ERR_KEY_CERT_INVALID; 2468 } 2469 if (ca_sign_algorithms != NULL && 2470 (r = sshkey_check_cert_sigtype(key, ca_sign_algorithms)) != 0) { 2471 *reason = "Certificate signed with disallowed algorithm"; 2472 return SSH_ERR_KEY_CERT_INVALID; 2473 } 2474 return 0; 2475 } 2476 2477 size_t 2478 sshkey_format_cert_validity(const struct sshkey_cert *cert, char *s, size_t l) 2479 { 2480 char from[32], to[32], ret[128]; 2481 2482 *from = *to = '\0'; 2483 if (cert->valid_after == 0 && 2484 cert->valid_before == 0xffffffffffffffffULL) 2485 return strlcpy(s, "forever", l); 2486 2487 if (cert->valid_after != 0) 2488 format_absolute_time(cert->valid_after, from, sizeof(from)); 2489 if (cert->valid_before != 0xffffffffffffffffULL) 2490 format_absolute_time(cert->valid_before, to, sizeof(to)); 2491 2492 if (cert->valid_after == 0) 2493 snprintf(ret, sizeof(ret), "before %s", to); 2494 else if (cert->valid_before == 0xffffffffffffffffULL) 2495 snprintf(ret, sizeof(ret), "after %s", from); 2496 else 2497 snprintf(ret, sizeof(ret), "from %s to %s", from, to); 2498 2499 return strlcpy(s, ret, l); 2500 } 2501 2502 /* Common serialization for FIDO private keys */ 2503 int 2504 sshkey_serialize_private_sk(const struct sshkey *key, struct sshbuf *b) 2505 { 2506 int r; 2507 2508 if ((r = sshbuf_put_cstring(b, key->sk_application)) != 0 || 2509 (r = sshbuf_put_u8(b, key->sk_flags)) != 0 || 2510 (r = sshbuf_put_stringb(b, key->sk_key_handle)) != 0 || 2511 (r = sshbuf_put_stringb(b, key->sk_reserved)) != 0) 2512 return r; 2513 2514 return 0; 2515 } 2516 2517 int 2518 sshkey_private_serialize_opt(struct sshkey *key, struct sshbuf *buf, 2519 enum sshkey_serialize_rep opts) 2520 { 2521 int r = SSH_ERR_INTERNAL_ERROR; 2522 int was_shielded = sshkey_is_shielded(key); 2523 struct sshbuf *b = NULL; 2524 const struct sshkey_impl *impl; 2525 2526 if ((impl = sshkey_impl_from_key(key)) == NULL) 2527 return SSH_ERR_INTERNAL_ERROR; 2528 if ((r = sshkey_unshield_private(key)) != 0) 2529 return r; 2530 if ((b = sshbuf_new()) == NULL) 2531 return SSH_ERR_ALLOC_FAIL; 2532 if ((r = sshbuf_put_cstring(b, sshkey_ssh_name(key))) != 0) 2533 goto out; 2534 if (sshkey_is_cert(key)) { 2535 if (key->cert == NULL || 2536 sshbuf_len(key->cert->certblob) == 0) { 2537 r = SSH_ERR_INVALID_ARGUMENT; 2538 goto out; 2539 } 2540 if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0) 2541 goto out; 2542 } 2543 if ((r = impl->funcs->serialize_private(key, b, opts)) != 0) 2544 goto out; 2545 2546 /* 2547 * success (but we still need to append the output to buf after 2548 * possibly re-shielding the private key) 2549 */ 2550 r = 0; 2551 out: 2552 if (was_shielded) 2553 r = sshkey_shield_private(key); 2554 if (r == 0) 2555 r = sshbuf_putb(buf, b); 2556 sshbuf_free(b); 2557 2558 return r; 2559 } 2560 2561 int 2562 sshkey_private_serialize(struct sshkey *key, struct sshbuf *b) 2563 { 2564 return sshkey_private_serialize_opt(key, b, 2565 SSHKEY_SERIALIZE_DEFAULT); 2566 } 2567 2568 /* Shared deserialization of FIDO private key components */ 2569 int 2570 sshkey_private_deserialize_sk(struct sshbuf *buf, struct sshkey *k) 2571 { 2572 int r; 2573 2574 if ((k->sk_key_handle = sshbuf_new()) == NULL || 2575 (k->sk_reserved = sshbuf_new()) == NULL) 2576 return SSH_ERR_ALLOC_FAIL; 2577 if ((r = sshbuf_get_cstring(buf, &k->sk_application, NULL)) != 0 || 2578 (r = sshbuf_get_u8(buf, &k->sk_flags)) != 0 || 2579 (r = sshbuf_get_stringb(buf, k->sk_key_handle)) != 0 || 2580 (r = sshbuf_get_stringb(buf, k->sk_reserved)) != 0) 2581 return r; 2582 2583 return 0; 2584 } 2585 2586 int 2587 sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp) 2588 { 2589 const struct sshkey_impl *impl; 2590 char *tname = NULL; 2591 char *expect_sk_application = NULL; 2592 u_char *expect_ed25519_pk = NULL; 2593 struct sshkey *k = NULL; 2594 int type, r = SSH_ERR_INTERNAL_ERROR; 2595 2596 if (kp != NULL) 2597 *kp = NULL; 2598 if ((r = sshbuf_get_cstring(buf, &tname, NULL)) != 0) 2599 goto out; 2600 type = sshkey_type_from_name(tname); 2601 if (sshkey_type_is_cert(type)) { 2602 /* 2603 * Certificate key private keys begin with the certificate 2604 * itself. Make sure this matches the type of the enclosing 2605 * private key. 2606 */ 2607 if ((r = sshkey_froms(buf, &k)) != 0) 2608 goto out; 2609 if (k->type != type) { 2610 r = SSH_ERR_KEY_CERT_MISMATCH; 2611 goto out; 2612 } 2613 /* For ECDSA keys, the group must match too */ 2614 if (k->type == KEY_ECDSA && 2615 k->ecdsa_nid != sshkey_ecdsa_nid_from_name(tname)) { 2616 r = SSH_ERR_KEY_CERT_MISMATCH; 2617 goto out; 2618 } 2619 /* 2620 * Several fields are redundant between certificate and 2621 * private key body, we require these to match. 2622 */ 2623 expect_sk_application = k->sk_application; 2624 expect_ed25519_pk = k->ed25519_pk; 2625 k->sk_application = NULL; 2626 k->ed25519_pk = NULL; 2627 /* XXX xmss too or refactor */ 2628 } else { 2629 if ((k = sshkey_new(type)) == NULL) { 2630 r = SSH_ERR_ALLOC_FAIL; 2631 goto out; 2632 } 2633 } 2634 if ((impl = sshkey_impl_from_type(type)) == NULL) { 2635 r = SSH_ERR_INTERNAL_ERROR; 2636 goto out; 2637 } 2638 if ((r = impl->funcs->deserialize_private(tname, buf, k)) != 0) 2639 goto out; 2640 2641 /* XXX xmss too or refactor */ 2642 if ((expect_sk_application != NULL && (k->sk_application == NULL || 2643 strcmp(expect_sk_application, k->sk_application) != 0)) || 2644 (expect_ed25519_pk != NULL && (k->ed25519_pk == NULL || 2645 memcmp(expect_ed25519_pk, k->ed25519_pk, ED25519_PK_SZ) != 0))) { 2646 r = SSH_ERR_KEY_CERT_MISMATCH; 2647 goto out; 2648 } 2649 /* success */ 2650 r = 0; 2651 if (kp != NULL) { 2652 *kp = k; 2653 k = NULL; 2654 } 2655 out: 2656 free(tname); 2657 sshkey_free(k); 2658 free(expect_sk_application); 2659 free(expect_ed25519_pk); 2660 return r; 2661 } 2662 2663 #ifdef WITH_OPENSSL 2664 int 2665 sshkey_ec_validate_public(const EC_GROUP *group, const EC_POINT *public) 2666 { 2667 EC_POINT *nq = NULL; 2668 BIGNUM *order = NULL, *x = NULL, *y = NULL, *tmp = NULL; 2669 int ret = SSH_ERR_KEY_INVALID_EC_VALUE; 2670 2671 /* 2672 * NB. This assumes OpenSSL has already verified that the public 2673 * point lies on the curve. This is done by EC_POINT_oct2point() 2674 * implicitly calling EC_POINT_is_on_curve(). If this code is ever 2675 * reachable with public points not unmarshalled using 2676 * EC_POINT_oct2point then the caller will need to explicitly check. 2677 */ 2678 2679 /* 2680 * We shouldn't ever hit this case because bignum_get_ecpoint() 2681 * refuses to load GF2m points. 2682 */ 2683 if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) != 2684 NID_X9_62_prime_field) 2685 goto out; 2686 2687 /* Q != infinity */ 2688 if (EC_POINT_is_at_infinity(group, public)) 2689 goto out; 2690 2691 if ((x = BN_new()) == NULL || 2692 (y = BN_new()) == NULL || 2693 (order = BN_new()) == NULL || 2694 (tmp = BN_new()) == NULL) { 2695 ret = SSH_ERR_ALLOC_FAIL; 2696 goto out; 2697 } 2698 2699 /* log2(x) > log2(order)/2, log2(y) > log2(order)/2 */ 2700 if (EC_GROUP_get_order(group, order, NULL) != 1 || 2701 EC_POINT_get_affine_coordinates_GFp(group, public, 2702 x, y, NULL) != 1) { 2703 ret = SSH_ERR_LIBCRYPTO_ERROR; 2704 goto out; 2705 } 2706 if (BN_num_bits(x) <= BN_num_bits(order) / 2 || 2707 BN_num_bits(y) <= BN_num_bits(order) / 2) 2708 goto out; 2709 2710 /* nQ == infinity (n == order of subgroup) */ 2711 if ((nq = EC_POINT_new(group)) == NULL) { 2712 ret = SSH_ERR_ALLOC_FAIL; 2713 goto out; 2714 } 2715 if (EC_POINT_mul(group, nq, NULL, public, order, NULL) != 1) { 2716 ret = SSH_ERR_LIBCRYPTO_ERROR; 2717 goto out; 2718 } 2719 if (EC_POINT_is_at_infinity(group, nq) != 1) 2720 goto out; 2721 2722 /* x < order - 1, y < order - 1 */ 2723 if (!BN_sub(tmp, order, BN_value_one())) { 2724 ret = SSH_ERR_LIBCRYPTO_ERROR; 2725 goto out; 2726 } 2727 if (BN_cmp(x, tmp) >= 0 || BN_cmp(y, tmp) >= 0) 2728 goto out; 2729 ret = 0; 2730 out: 2731 BN_clear_free(x); 2732 BN_clear_free(y); 2733 BN_clear_free(order); 2734 BN_clear_free(tmp); 2735 EC_POINT_free(nq); 2736 return ret; 2737 } 2738 2739 int 2740 sshkey_ec_validate_private(const EC_KEY *key) 2741 { 2742 BIGNUM *order = NULL, *tmp = NULL; 2743 int ret = SSH_ERR_KEY_INVALID_EC_VALUE; 2744 2745 if ((order = BN_new()) == NULL || (tmp = BN_new()) == NULL) { 2746 ret = SSH_ERR_ALLOC_FAIL; 2747 goto out; 2748 } 2749 2750 /* log2(private) > log2(order)/2 */ 2751 if (EC_GROUP_get_order(EC_KEY_get0_group(key), order, NULL) != 1) { 2752 ret = SSH_ERR_LIBCRYPTO_ERROR; 2753 goto out; 2754 } 2755 if (BN_num_bits(EC_KEY_get0_private_key(key)) <= 2756 BN_num_bits(order) / 2) 2757 goto out; 2758 2759 /* private < order - 1 */ 2760 if (!BN_sub(tmp, order, BN_value_one())) { 2761 ret = SSH_ERR_LIBCRYPTO_ERROR; 2762 goto out; 2763 } 2764 if (BN_cmp(EC_KEY_get0_private_key(key), tmp) >= 0) 2765 goto out; 2766 ret = 0; 2767 out: 2768 BN_clear_free(order); 2769 BN_clear_free(tmp); 2770 return ret; 2771 } 2772 2773 void 2774 sshkey_dump_ec_point(const EC_GROUP *group, const EC_POINT *point) 2775 { 2776 BIGNUM *x = NULL, *y = NULL; 2777 2778 if (point == NULL) { 2779 fputs("point=(NULL)\n", stderr); 2780 return; 2781 } 2782 if ((x = BN_new()) == NULL || (y = BN_new()) == NULL) { 2783 fprintf(stderr, "%s: BN_new failed\n", __func__); 2784 goto out; 2785 } 2786 if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) != 2787 NID_X9_62_prime_field) { 2788 fprintf(stderr, "%s: group is not a prime field\n", __func__); 2789 goto out; 2790 } 2791 if (EC_POINT_get_affine_coordinates_GFp(group, point, 2792 x, y, NULL) != 1) { 2793 fprintf(stderr, "%s: EC_POINT_get_affine_coordinates_GFp\n", 2794 __func__); 2795 goto out; 2796 } 2797 fputs("x=", stderr); 2798 BN_print_fp(stderr, x); 2799 fputs("\ny=", stderr); 2800 BN_print_fp(stderr, y); 2801 fputs("\n", stderr); 2802 out: 2803 BN_clear_free(x); 2804 BN_clear_free(y); 2805 } 2806 2807 void 2808 sshkey_dump_ec_key(const EC_KEY *key) 2809 { 2810 const BIGNUM *exponent; 2811 2812 sshkey_dump_ec_point(EC_KEY_get0_group(key), 2813 EC_KEY_get0_public_key(key)); 2814 fputs("exponent=", stderr); 2815 if ((exponent = EC_KEY_get0_private_key(key)) == NULL) 2816 fputs("(NULL)", stderr); 2817 else 2818 BN_print_fp(stderr, EC_KEY_get0_private_key(key)); 2819 fputs("\n", stderr); 2820 } 2821 #endif /* WITH_OPENSSL */ 2822 2823 static int 2824 sshkey_private_to_blob2(struct sshkey *prv, struct sshbuf *blob, 2825 const char *passphrase, const char *comment, const char *ciphername, 2826 int rounds) 2827 { 2828 u_char *cp, *key = NULL, *pubkeyblob = NULL; 2829 u_char salt[SALT_LEN]; 2830 size_t i, pubkeylen, keylen, ivlen, blocksize, authlen; 2831 u_int check; 2832 int r = SSH_ERR_INTERNAL_ERROR; 2833 struct sshcipher_ctx *ciphercontext = NULL; 2834 const struct sshcipher *cipher; 2835 const char *kdfname = KDFNAME; 2836 struct sshbuf *encoded = NULL, *encrypted = NULL, *kdf = NULL; 2837 2838 if (rounds <= 0) 2839 rounds = DEFAULT_ROUNDS; 2840 if (passphrase == NULL || !strlen(passphrase)) { 2841 ciphername = "none"; 2842 kdfname = "none"; 2843 } else if (ciphername == NULL) 2844 ciphername = DEFAULT_CIPHERNAME; 2845 if ((cipher = cipher_by_name(ciphername)) == NULL) { 2846 r = SSH_ERR_INVALID_ARGUMENT; 2847 goto out; 2848 } 2849 2850 if ((kdf = sshbuf_new()) == NULL || 2851 (encoded = sshbuf_new()) == NULL || 2852 (encrypted = sshbuf_new()) == NULL) { 2853 r = SSH_ERR_ALLOC_FAIL; 2854 goto out; 2855 } 2856 blocksize = cipher_blocksize(cipher); 2857 keylen = cipher_keylen(cipher); 2858 ivlen = cipher_ivlen(cipher); 2859 authlen = cipher_authlen(cipher); 2860 if ((key = calloc(1, keylen + ivlen)) == NULL) { 2861 r = SSH_ERR_ALLOC_FAIL; 2862 goto out; 2863 } 2864 if (strcmp(kdfname, "bcrypt") == 0) { 2865 arc4random_buf(salt, SALT_LEN); 2866 if (bcrypt_pbkdf(passphrase, strlen(passphrase), 2867 salt, SALT_LEN, key, keylen + ivlen, rounds) < 0) { 2868 r = SSH_ERR_INVALID_ARGUMENT; 2869 goto out; 2870 } 2871 if ((r = sshbuf_put_string(kdf, salt, SALT_LEN)) != 0 || 2872 (r = sshbuf_put_u32(kdf, rounds)) != 0) 2873 goto out; 2874 } else if (strcmp(kdfname, "none") != 0) { 2875 /* Unsupported KDF type */ 2876 r = SSH_ERR_KEY_UNKNOWN_CIPHER; 2877 goto out; 2878 } 2879 if ((r = cipher_init(&ciphercontext, cipher, key, keylen, 2880 key + keylen, ivlen, 1)) != 0) 2881 goto out; 2882 2883 if ((r = sshbuf_put(encoded, AUTH_MAGIC, sizeof(AUTH_MAGIC))) != 0 || 2884 (r = sshbuf_put_cstring(encoded, ciphername)) != 0 || 2885 (r = sshbuf_put_cstring(encoded, kdfname)) != 0 || 2886 (r = sshbuf_put_stringb(encoded, kdf)) != 0 || 2887 (r = sshbuf_put_u32(encoded, 1)) != 0 || /* number of keys */ 2888 (r = sshkey_to_blob(prv, &pubkeyblob, &pubkeylen)) != 0 || 2889 (r = sshbuf_put_string(encoded, pubkeyblob, pubkeylen)) != 0) 2890 goto out; 2891 2892 /* set up the buffer that will be encrypted */ 2893 2894 /* Random check bytes */ 2895 check = arc4random(); 2896 if ((r = sshbuf_put_u32(encrypted, check)) != 0 || 2897 (r = sshbuf_put_u32(encrypted, check)) != 0) 2898 goto out; 2899 2900 /* append private key and comment*/ 2901 if ((r = sshkey_private_serialize_opt(prv, encrypted, 2902 SSHKEY_SERIALIZE_FULL)) != 0 || 2903 (r = sshbuf_put_cstring(encrypted, comment)) != 0) 2904 goto out; 2905 2906 /* padding */ 2907 i = 0; 2908 while (sshbuf_len(encrypted) % blocksize) { 2909 if ((r = sshbuf_put_u8(encrypted, ++i & 0xff)) != 0) 2910 goto out; 2911 } 2912 2913 /* length in destination buffer */ 2914 if ((r = sshbuf_put_u32(encoded, sshbuf_len(encrypted))) != 0) 2915 goto out; 2916 2917 /* encrypt */ 2918 if ((r = sshbuf_reserve(encoded, 2919 sshbuf_len(encrypted) + authlen, &cp)) != 0) 2920 goto out; 2921 if ((r = cipher_crypt(ciphercontext, 0, cp, 2922 sshbuf_ptr(encrypted), sshbuf_len(encrypted), 0, authlen)) != 0) 2923 goto out; 2924 2925 sshbuf_reset(blob); 2926 2927 /* assemble uuencoded key */ 2928 if ((r = sshbuf_put(blob, MARK_BEGIN, MARK_BEGIN_LEN)) != 0 || 2929 (r = sshbuf_dtob64(encoded, blob, 1)) != 0 || 2930 (r = sshbuf_put(blob, MARK_END, MARK_END_LEN)) != 0) 2931 goto out; 2932 2933 /* success */ 2934 r = 0; 2935 2936 out: 2937 sshbuf_free(kdf); 2938 sshbuf_free(encoded); 2939 sshbuf_free(encrypted); 2940 cipher_free(ciphercontext); 2941 explicit_bzero(salt, sizeof(salt)); 2942 if (key != NULL) 2943 freezero(key, keylen + ivlen); 2944 if (pubkeyblob != NULL) 2945 freezero(pubkeyblob, pubkeylen); 2946 return r; 2947 } 2948 2949 static int 2950 private2_uudecode(struct sshbuf *blob, struct sshbuf **decodedp) 2951 { 2952 const u_char *cp; 2953 size_t encoded_len; 2954 int r; 2955 u_char last; 2956 struct sshbuf *encoded = NULL, *decoded = NULL; 2957 2958 if (blob == NULL || decodedp == NULL) 2959 return SSH_ERR_INVALID_ARGUMENT; 2960 2961 *decodedp = NULL; 2962 2963 if ((encoded = sshbuf_new()) == NULL || 2964 (decoded = sshbuf_new()) == NULL) { 2965 r = SSH_ERR_ALLOC_FAIL; 2966 goto out; 2967 } 2968 2969 /* check preamble */ 2970 cp = sshbuf_ptr(blob); 2971 encoded_len = sshbuf_len(blob); 2972 if (encoded_len < (MARK_BEGIN_LEN + MARK_END_LEN) || 2973 memcmp(cp, MARK_BEGIN, MARK_BEGIN_LEN) != 0) { 2974 r = SSH_ERR_INVALID_FORMAT; 2975 goto out; 2976 } 2977 cp += MARK_BEGIN_LEN; 2978 encoded_len -= MARK_BEGIN_LEN; 2979 2980 /* Look for end marker, removing whitespace as we go */ 2981 while (encoded_len > 0) { 2982 if (*cp != '\n' && *cp != '\r') { 2983 if ((r = sshbuf_put_u8(encoded, *cp)) != 0) 2984 goto out; 2985 } 2986 last = *cp; 2987 encoded_len--; 2988 cp++; 2989 if (last == '\n') { 2990 if (encoded_len >= MARK_END_LEN && 2991 memcmp(cp, MARK_END, MARK_END_LEN) == 0) { 2992 /* \0 terminate */ 2993 if ((r = sshbuf_put_u8(encoded, 0)) != 0) 2994 goto out; 2995 break; 2996 } 2997 } 2998 } 2999 if (encoded_len == 0) { 3000 r = SSH_ERR_INVALID_FORMAT; 3001 goto out; 3002 } 3003 3004 /* decode base64 */ 3005 if ((r = sshbuf_b64tod(decoded, (const char *)sshbuf_ptr(encoded))) != 0) 3006 goto out; 3007 3008 /* check magic */ 3009 if (sshbuf_len(decoded) < sizeof(AUTH_MAGIC) || 3010 memcmp(sshbuf_ptr(decoded), AUTH_MAGIC, sizeof(AUTH_MAGIC))) { 3011 r = SSH_ERR_INVALID_FORMAT; 3012 goto out; 3013 } 3014 /* success */ 3015 *decodedp = decoded; 3016 decoded = NULL; 3017 r = 0; 3018 out: 3019 sshbuf_free(encoded); 3020 sshbuf_free(decoded); 3021 return r; 3022 } 3023 3024 static int 3025 private2_decrypt(struct sshbuf *decoded, const char *passphrase, 3026 struct sshbuf **decryptedp, struct sshkey **pubkeyp) 3027 { 3028 char *ciphername = NULL, *kdfname = NULL; 3029 const struct sshcipher *cipher = NULL; 3030 int r = SSH_ERR_INTERNAL_ERROR; 3031 size_t keylen = 0, ivlen = 0, authlen = 0, slen = 0; 3032 struct sshbuf *kdf = NULL, *decrypted = NULL; 3033 struct sshcipher_ctx *ciphercontext = NULL; 3034 struct sshkey *pubkey = NULL; 3035 u_char *key = NULL, *salt = NULL, *dp; 3036 u_int blocksize, rounds, nkeys, encrypted_len, check1, check2; 3037 3038 if (decoded == NULL || decryptedp == NULL || pubkeyp == NULL) 3039 return SSH_ERR_INVALID_ARGUMENT; 3040 3041 *decryptedp = NULL; 3042 *pubkeyp = NULL; 3043 3044 if ((decrypted = sshbuf_new()) == NULL) { 3045 r = SSH_ERR_ALLOC_FAIL; 3046 goto out; 3047 } 3048 3049 /* parse public portion of key */ 3050 if ((r = sshbuf_consume(decoded, sizeof(AUTH_MAGIC))) != 0 || 3051 (r = sshbuf_get_cstring(decoded, &ciphername, NULL)) != 0 || 3052 (r = sshbuf_get_cstring(decoded, &kdfname, NULL)) != 0 || 3053 (r = sshbuf_froms(decoded, &kdf)) != 0 || 3054 (r = sshbuf_get_u32(decoded, &nkeys)) != 0) 3055 goto out; 3056 3057 if (nkeys != 1) { 3058 /* XXX only one key supported at present */ 3059 r = SSH_ERR_INVALID_FORMAT; 3060 goto out; 3061 } 3062 3063 if ((r = sshkey_froms(decoded, &pubkey)) != 0 || 3064 (r = sshbuf_get_u32(decoded, &encrypted_len)) != 0) 3065 goto out; 3066 3067 if ((cipher = cipher_by_name(ciphername)) == NULL) { 3068 r = SSH_ERR_KEY_UNKNOWN_CIPHER; 3069 goto out; 3070 } 3071 if (strcmp(kdfname, "none") != 0 && strcmp(kdfname, "bcrypt") != 0) { 3072 r = SSH_ERR_KEY_UNKNOWN_CIPHER; 3073 goto out; 3074 } 3075 if (strcmp(kdfname, "none") == 0 && strcmp(ciphername, "none") != 0) { 3076 r = SSH_ERR_INVALID_FORMAT; 3077 goto out; 3078 } 3079 if ((passphrase == NULL || strlen(passphrase) == 0) && 3080 strcmp(kdfname, "none") != 0) { 3081 /* passphrase required */ 3082 r = SSH_ERR_KEY_WRONG_PASSPHRASE; 3083 goto out; 3084 } 3085 3086 /* check size of encrypted key blob */ 3087 blocksize = cipher_blocksize(cipher); 3088 if (encrypted_len < blocksize || (encrypted_len % blocksize) != 0) { 3089 r = SSH_ERR_INVALID_FORMAT; 3090 goto out; 3091 } 3092 3093 /* setup key */ 3094 keylen = cipher_keylen(cipher); 3095 ivlen = cipher_ivlen(cipher); 3096 authlen = cipher_authlen(cipher); 3097 if ((key = calloc(1, keylen + ivlen)) == NULL) { 3098 r = SSH_ERR_ALLOC_FAIL; 3099 goto out; 3100 } 3101 if (strcmp(kdfname, "bcrypt") == 0) { 3102 if ((r = sshbuf_get_string(kdf, &salt, &slen)) != 0 || 3103 (r = sshbuf_get_u32(kdf, &rounds)) != 0) 3104 goto out; 3105 if (bcrypt_pbkdf(passphrase, strlen(passphrase), salt, slen, 3106 key, keylen + ivlen, rounds) < 0) { 3107 r = SSH_ERR_INVALID_FORMAT; 3108 goto out; 3109 } 3110 } 3111 3112 /* check that an appropriate amount of auth data is present */ 3113 if (sshbuf_len(decoded) < authlen || 3114 sshbuf_len(decoded) - authlen < encrypted_len) { 3115 r = SSH_ERR_INVALID_FORMAT; 3116 goto out; 3117 } 3118 3119 /* decrypt private portion of key */ 3120 if ((r = sshbuf_reserve(decrypted, encrypted_len, &dp)) != 0 || 3121 (r = cipher_init(&ciphercontext, cipher, key, keylen, 3122 key + keylen, ivlen, 0)) != 0) 3123 goto out; 3124 if ((r = cipher_crypt(ciphercontext, 0, dp, sshbuf_ptr(decoded), 3125 encrypted_len, 0, authlen)) != 0) { 3126 /* an integrity error here indicates an incorrect passphrase */ 3127 if (r == SSH_ERR_MAC_INVALID) 3128 r = SSH_ERR_KEY_WRONG_PASSPHRASE; 3129 goto out; 3130 } 3131 if ((r = sshbuf_consume(decoded, encrypted_len + authlen)) != 0) 3132 goto out; 3133 /* there should be no trailing data */ 3134 if (sshbuf_len(decoded) != 0) { 3135 r = SSH_ERR_INVALID_FORMAT; 3136 goto out; 3137 } 3138 3139 /* check check bytes */ 3140 if ((r = sshbuf_get_u32(decrypted, &check1)) != 0 || 3141 (r = sshbuf_get_u32(decrypted, &check2)) != 0) 3142 goto out; 3143 if (check1 != check2) { 3144 r = SSH_ERR_KEY_WRONG_PASSPHRASE; 3145 goto out; 3146 } 3147 /* success */ 3148 *decryptedp = decrypted; 3149 decrypted = NULL; 3150 *pubkeyp = pubkey; 3151 pubkey = NULL; 3152 r = 0; 3153 out: 3154 cipher_free(ciphercontext); 3155 free(ciphername); 3156 free(kdfname); 3157 sshkey_free(pubkey); 3158 if (salt != NULL) { 3159 explicit_bzero(salt, slen); 3160 free(salt); 3161 } 3162 if (key != NULL) { 3163 explicit_bzero(key, keylen + ivlen); 3164 free(key); 3165 } 3166 sshbuf_free(kdf); 3167 sshbuf_free(decrypted); 3168 return r; 3169 } 3170 3171 static int 3172 sshkey_parse_private2(struct sshbuf *blob, int type, const char *passphrase, 3173 struct sshkey **keyp, char **commentp) 3174 { 3175 char *comment = NULL; 3176 int r = SSH_ERR_INTERNAL_ERROR; 3177 struct sshbuf *decoded = NULL, *decrypted = NULL; 3178 struct sshkey *k = NULL, *pubkey = NULL; 3179 3180 if (keyp != NULL) 3181 *keyp = NULL; 3182 if (commentp != NULL) 3183 *commentp = NULL; 3184 3185 /* Undo base64 encoding and decrypt the private section */ 3186 if ((r = private2_uudecode(blob, &decoded)) != 0 || 3187 (r = private2_decrypt(decoded, passphrase, 3188 &decrypted, &pubkey)) != 0) 3189 goto out; 3190 3191 if (type != KEY_UNSPEC && 3192 sshkey_type_plain(type) != sshkey_type_plain(pubkey->type)) { 3193 r = SSH_ERR_KEY_TYPE_MISMATCH; 3194 goto out; 3195 } 3196 3197 /* Load the private key and comment */ 3198 if ((r = sshkey_private_deserialize(decrypted, &k)) != 0 || 3199 (r = sshbuf_get_cstring(decrypted, &comment, NULL)) != 0) 3200 goto out; 3201 3202 /* Check deterministic padding after private section */ 3203 if ((r = private2_check_padding(decrypted)) != 0) 3204 goto out; 3205 3206 /* Check that the public key in the envelope matches the private key */ 3207 if (!sshkey_equal(pubkey, k)) { 3208 r = SSH_ERR_INVALID_FORMAT; 3209 goto out; 3210 } 3211 3212 /* success */ 3213 r = 0; 3214 if (keyp != NULL) { 3215 *keyp = k; 3216 k = NULL; 3217 } 3218 if (commentp != NULL) { 3219 *commentp = comment; 3220 comment = NULL; 3221 } 3222 out: 3223 free(comment); 3224 sshbuf_free(decoded); 3225 sshbuf_free(decrypted); 3226 sshkey_free(k); 3227 sshkey_free(pubkey); 3228 return r; 3229 } 3230 3231 static int 3232 sshkey_parse_private2_pubkey(struct sshbuf *blob, int type, 3233 struct sshkey **keyp) 3234 { 3235 int r = SSH_ERR_INTERNAL_ERROR; 3236 struct sshbuf *decoded = NULL; 3237 struct sshkey *pubkey = NULL; 3238 u_int nkeys = 0; 3239 3240 if (keyp != NULL) 3241 *keyp = NULL; 3242 3243 if ((r = private2_uudecode(blob, &decoded)) != 0) 3244 goto out; 3245 /* parse public key from unencrypted envelope */ 3246 if ((r = sshbuf_consume(decoded, sizeof(AUTH_MAGIC))) != 0 || 3247 (r = sshbuf_skip_string(decoded)) != 0 || /* cipher */ 3248 (r = sshbuf_skip_string(decoded)) != 0 || /* KDF alg */ 3249 (r = sshbuf_skip_string(decoded)) != 0 || /* KDF hint */ 3250 (r = sshbuf_get_u32(decoded, &nkeys)) != 0) 3251 goto out; 3252 3253 if (nkeys != 1) { 3254 /* XXX only one key supported at present */ 3255 r = SSH_ERR_INVALID_FORMAT; 3256 goto out; 3257 } 3258 3259 /* Parse the public key */ 3260 if ((r = sshkey_froms(decoded, &pubkey)) != 0) 3261 goto out; 3262 3263 if (type != KEY_UNSPEC && 3264 sshkey_type_plain(type) != sshkey_type_plain(pubkey->type)) { 3265 r = SSH_ERR_KEY_TYPE_MISMATCH; 3266 goto out; 3267 } 3268 3269 /* success */ 3270 r = 0; 3271 if (keyp != NULL) { 3272 *keyp = pubkey; 3273 pubkey = NULL; 3274 } 3275 out: 3276 sshbuf_free(decoded); 3277 sshkey_free(pubkey); 3278 return r; 3279 } 3280 3281 #ifdef WITH_OPENSSL 3282 /* convert SSH v2 key to PEM or PKCS#8 format */ 3283 static int 3284 sshkey_private_to_blob_pem_pkcs8(struct sshkey *key, struct sshbuf *buf, 3285 int format, const char *_passphrase, const char *comment) 3286 { 3287 int was_shielded = sshkey_is_shielded(key); 3288 int success, r; 3289 int blen, len = strlen(_passphrase); 3290 u_char *passphrase = (len > 0) ? __UNCONST(_passphrase) : NULL; 3291 const EVP_CIPHER *cipher = (len > 0) ? EVP_aes_128_cbc() : NULL; 3292 char *bptr; 3293 BIO *bio = NULL; 3294 struct sshbuf *blob; 3295 EVP_PKEY *pkey = NULL; 3296 3297 if (len > 0 && len <= 4) 3298 return SSH_ERR_PASSPHRASE_TOO_SHORT; 3299 if ((blob = sshbuf_new()) == NULL) 3300 return SSH_ERR_ALLOC_FAIL; 3301 if ((bio = BIO_new(BIO_s_mem())) == NULL) { 3302 r = SSH_ERR_ALLOC_FAIL; 3303 goto out; 3304 } 3305 if ((r = sshkey_unshield_private(key)) != 0) 3306 goto out; 3307 3308 switch (key->type) { 3309 #ifdef WITH_DSA 3310 case KEY_DSA: 3311 if (format == SSHKEY_PRIVATE_PEM) { 3312 success = PEM_write_bio_DSAPrivateKey(bio, key->dsa, 3313 cipher, passphrase, len, NULL, NULL); 3314 } else { 3315 if ((pkey = EVP_PKEY_new()) == NULL) { 3316 r = SSH_ERR_ALLOC_FAIL; 3317 goto out; 3318 } 3319 success = EVP_PKEY_set1_DSA(pkey, key->dsa); 3320 } 3321 break; 3322 #endif 3323 case KEY_ECDSA: 3324 if (format == SSHKEY_PRIVATE_PEM) { 3325 success = PEM_write_bio_ECPrivateKey(bio, 3326 EVP_PKEY_get0_EC_KEY(key->pkey), 3327 cipher, passphrase, len, NULL, NULL); 3328 } else { 3329 pkey = key->pkey; 3330 EVP_PKEY_up_ref(key->pkey); 3331 success = 1; 3332 } 3333 break; 3334 case KEY_RSA: 3335 if (format == SSHKEY_PRIVATE_PEM) { 3336 success = PEM_write_bio_RSAPrivateKey(bio, 3337 EVP_PKEY_get0_RSA(key->pkey), 3338 cipher, passphrase, len, NULL, NULL); 3339 } else { 3340 pkey = key->pkey; 3341 EVP_PKEY_up_ref(key->pkey); 3342 success = 1; 3343 } 3344 break; 3345 default: 3346 success = 0; 3347 break; 3348 } 3349 if (success == 0) { 3350 r = SSH_ERR_LIBCRYPTO_ERROR; 3351 goto out; 3352 } 3353 if (format == SSHKEY_PRIVATE_PKCS8) { 3354 if ((success = PEM_write_bio_PrivateKey(bio, pkey, cipher, 3355 passphrase, len, NULL, NULL)) == 0) { 3356 r = SSH_ERR_LIBCRYPTO_ERROR; 3357 goto out; 3358 } 3359 } 3360 if ((blen = BIO_get_mem_data(bio, &bptr)) <= 0) { 3361 r = SSH_ERR_INTERNAL_ERROR; 3362 goto out; 3363 } 3364 if ((r = sshbuf_put(blob, bptr, blen)) != 0) 3365 goto out; 3366 r = 0; 3367 out: 3368 if (was_shielded) 3369 r = sshkey_shield_private(key); 3370 if (r == 0) 3371 r = sshbuf_putb(buf, blob); 3372 3373 EVP_PKEY_free(pkey); 3374 sshbuf_free(blob); 3375 BIO_free(bio); 3376 return r; 3377 } 3378 #endif /* WITH_OPENSSL */ 3379 3380 /* Serialise "key" to buffer "blob" */ 3381 int 3382 sshkey_private_to_fileblob(struct sshkey *key, struct sshbuf *blob, 3383 const char *passphrase, const char *comment, 3384 int format, const char *openssh_format_cipher, int openssh_format_rounds) 3385 { 3386 switch (key->type) { 3387 #ifdef WITH_OPENSSL 3388 case KEY_DSA: 3389 case KEY_ECDSA: 3390 case KEY_RSA: 3391 break; /* see below */ 3392 #endif /* WITH_OPENSSL */ 3393 case KEY_ED25519: 3394 case KEY_ED25519_SK: 3395 #ifdef WITH_XMSS 3396 case KEY_XMSS: 3397 #endif /* WITH_XMSS */ 3398 #ifdef WITH_OPENSSL 3399 case KEY_ECDSA_SK: 3400 #endif /* WITH_OPENSSL */ 3401 return sshkey_private_to_blob2(key, blob, passphrase, 3402 comment, openssh_format_cipher, openssh_format_rounds); 3403 default: 3404 return SSH_ERR_KEY_TYPE_UNKNOWN; 3405 } 3406 3407 #ifdef WITH_OPENSSL 3408 switch (format) { 3409 case SSHKEY_PRIVATE_OPENSSH: 3410 return sshkey_private_to_blob2(key, blob, passphrase, 3411 comment, openssh_format_cipher, openssh_format_rounds); 3412 case SSHKEY_PRIVATE_PEM: 3413 case SSHKEY_PRIVATE_PKCS8: 3414 return sshkey_private_to_blob_pem_pkcs8(key, blob, 3415 format, passphrase, comment); 3416 default: 3417 return SSH_ERR_INVALID_ARGUMENT; 3418 } 3419 #endif /* WITH_OPENSSL */ 3420 } 3421 3422 #ifdef WITH_OPENSSL 3423 static int 3424 translate_libcrypto_error(unsigned long pem_err) 3425 { 3426 int pem_reason = ERR_GET_REASON(pem_err); 3427 3428 switch (ERR_GET_LIB(pem_err)) { 3429 case ERR_LIB_PEM: 3430 switch (pem_reason) { 3431 case PEM_R_BAD_PASSWORD_READ: 3432 case PEM_R_PROBLEMS_GETTING_PASSWORD: 3433 case PEM_R_BAD_DECRYPT: 3434 return SSH_ERR_KEY_WRONG_PASSPHRASE; 3435 default: 3436 return SSH_ERR_INVALID_FORMAT; 3437 } 3438 case ERR_LIB_EVP: 3439 switch (pem_reason) { 3440 case EVP_R_BAD_DECRYPT: 3441 return SSH_ERR_KEY_WRONG_PASSPHRASE; 3442 #ifdef EVP_R_BN_DECODE_ERROR 3443 case EVP_R_BN_DECODE_ERROR: 3444 #endif 3445 case EVP_R_DECODE_ERROR: 3446 #ifdef EVP_R_PRIVATE_KEY_DECODE_ERROR 3447 case EVP_R_PRIVATE_KEY_DECODE_ERROR: 3448 #endif 3449 return SSH_ERR_INVALID_FORMAT; 3450 default: 3451 return SSH_ERR_LIBCRYPTO_ERROR; 3452 } 3453 case ERR_LIB_ASN1: 3454 return SSH_ERR_INVALID_FORMAT; 3455 } 3456 return SSH_ERR_LIBCRYPTO_ERROR; 3457 } 3458 3459 static void 3460 clear_libcrypto_errors(void) 3461 { 3462 while (ERR_get_error() != 0) 3463 ; 3464 } 3465 3466 /* 3467 * Translate OpenSSL error codes to determine whether 3468 * passphrase is required/incorrect. 3469 */ 3470 static int 3471 convert_libcrypto_error(void) 3472 { 3473 /* 3474 * Some password errors are reported at the beginning 3475 * of the error queue. 3476 */ 3477 if (translate_libcrypto_error(ERR_peek_error()) == 3478 SSH_ERR_KEY_WRONG_PASSPHRASE) 3479 return SSH_ERR_KEY_WRONG_PASSPHRASE; 3480 return translate_libcrypto_error(ERR_peek_last_error()); 3481 } 3482 3483 #if 0 3484 static int 3485 pem_passphrase_cb(char *buf, int size, int rwflag, void *u) 3486 { 3487 char *p = (char *)u; 3488 size_t len; 3489 3490 if (p == NULL || (len = strlen(p)) == 0) 3491 return -1; 3492 if (size < 0 || len > (size_t)size) 3493 return -1; 3494 memcpy(buf, p, len); 3495 return (int)len; 3496 } 3497 #endif 3498 3499 static int 3500 sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type, 3501 const char *passphrase, struct sshkey **keyp) 3502 { 3503 EVP_PKEY *pk = NULL; 3504 struct sshkey *prv = NULL; 3505 BIO *bio = NULL; 3506 int r; 3507 RSA *rsa = NULL; 3508 EC_KEY *ecdsa = NULL; 3509 3510 if (keyp != NULL) 3511 *keyp = NULL; 3512 3513 if ((bio = BIO_new(BIO_s_mem())) == NULL || sshbuf_len(blob) > INT_MAX) 3514 return SSH_ERR_ALLOC_FAIL; 3515 if (BIO_write(bio, sshbuf_ptr(blob), sshbuf_len(blob)) != 3516 (int)sshbuf_len(blob)) { 3517 r = SSH_ERR_ALLOC_FAIL; 3518 goto out; 3519 } 3520 3521 clear_libcrypto_errors(); 3522 if ((pk = PEM_read_bio_PrivateKey(bio, NULL, NULL, 3523 __UNCONST(passphrase))) == NULL) { 3524 /* 3525 * libcrypto may return various ASN.1 errors when attempting 3526 * to parse a key with an incorrect passphrase. 3527 * Treat all format errors as "incorrect passphrase" if a 3528 * passphrase was supplied. 3529 */ 3530 if (passphrase != NULL && *passphrase != '\0') 3531 r = SSH_ERR_KEY_WRONG_PASSPHRASE; 3532 else 3533 r = convert_libcrypto_error(); 3534 goto out; 3535 } 3536 if (EVP_PKEY_base_id(pk) == EVP_PKEY_RSA && 3537 (type == KEY_UNSPEC || type == KEY_RSA)) { 3538 if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) { 3539 r = SSH_ERR_ALLOC_FAIL; 3540 goto out; 3541 } 3542 if ((rsa = EVP_PKEY_get1_RSA(pk)) == NULL) { 3543 r = SSH_ERR_LIBCRYPTO_ERROR; 3544 goto out; 3545 } 3546 prv->type = KEY_RSA; 3547 #ifdef DEBUG_PK 3548 RSA_print_fp(stderr, rsa, 8); 3549 #endif 3550 if (RSA_blinding_on(rsa, NULL) != 1 || 3551 EVP_PKEY_set1_RSA(pk, rsa) != 1) { 3552 r = SSH_ERR_LIBCRYPTO_ERROR; 3553 goto out; 3554 } 3555 EVP_PKEY_up_ref(pk); 3556 prv->pkey = pk; 3557 if ((r = sshkey_check_rsa_length(prv, 0)) != 0) 3558 goto out; 3559 #ifdef WITH_DSA 3560 } else if (EVP_PKEY_base_id(pk) == EVP_PKEY_DSA && 3561 (type == KEY_UNSPEC || type == KEY_DSA)) { 3562 if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) { 3563 r = SSH_ERR_ALLOC_FAIL; 3564 goto out; 3565 } 3566 prv->dsa = EVP_PKEY_get1_DSA(pk); 3567 prv->type = KEY_DSA; 3568 #ifdef DEBUG_PK 3569 DSA_print_fp(stderr, prv->dsa, 8); 3570 #endif 3571 #endif 3572 } else if (EVP_PKEY_base_id(pk) == EVP_PKEY_EC && 3573 (type == KEY_UNSPEC || type == KEY_ECDSA)) { 3574 if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) { 3575 r = SSH_ERR_ALLOC_FAIL; 3576 goto out; 3577 } 3578 if ((prv->ecdsa_nid = sshkey_ecdsa_fixup_group(pk)) == -1 || 3579 (ecdsa = EVP_PKEY_get1_EC_KEY(pk)) == NULL) { 3580 r = SSH_ERR_LIBCRYPTO_ERROR; 3581 goto out; 3582 } 3583 prv->type = KEY_ECDSA; 3584 if (sshkey_curve_nid_to_name(prv->ecdsa_nid) == NULL || 3585 sshkey_ec_validate_public(EC_KEY_get0_group(ecdsa), 3586 EC_KEY_get0_public_key(ecdsa)) != 0 || 3587 sshkey_ec_validate_private(ecdsa) != 0) { 3588 r = SSH_ERR_INVALID_FORMAT; 3589 goto out; 3590 } 3591 EVP_PKEY_up_ref(pk); 3592 prv->pkey = pk; 3593 #ifdef DEBUG_PK 3594 if (prv != NULL && prv->pkey != NULL) 3595 sshkey_dump_ec_key(EVP_PKEY_get0_EC_KEY(prv->pkey)); 3596 #endif 3597 } else if (EVP_PKEY_base_id(pk) == EVP_PKEY_ED25519 && 3598 (type == KEY_UNSPEC || type == KEY_ED25519)) { 3599 size_t len; 3600 3601 if ((prv = sshkey_new(KEY_UNSPEC)) == NULL || 3602 (prv->ed25519_sk = calloc(1, ED25519_SK_SZ)) == NULL || 3603 (prv->ed25519_pk = calloc(1, ED25519_PK_SZ)) == NULL) { 3604 r = SSH_ERR_ALLOC_FAIL; 3605 goto out; 3606 } 3607 prv->type = KEY_ED25519; 3608 len = ED25519_PK_SZ; 3609 if (!EVP_PKEY_get_raw_public_key(pk, prv->ed25519_pk, &len)) { 3610 r = SSH_ERR_LIBCRYPTO_ERROR; 3611 goto out; 3612 } 3613 if (len != ED25519_PK_SZ) { 3614 r = SSH_ERR_INVALID_FORMAT; 3615 goto out; 3616 } 3617 len = ED25519_SK_SZ - ED25519_PK_SZ; 3618 if (!EVP_PKEY_get_raw_private_key(pk, prv->ed25519_sk, &len)) { 3619 r = SSH_ERR_LIBCRYPTO_ERROR; 3620 goto out; 3621 } 3622 if (len != ED25519_SK_SZ - ED25519_PK_SZ) { 3623 r = SSH_ERR_INVALID_FORMAT; 3624 goto out; 3625 } 3626 /* Append the public key to our private key */ 3627 memcpy(prv->ed25519_sk + (ED25519_SK_SZ - ED25519_PK_SZ), 3628 prv->ed25519_pk, ED25519_PK_SZ); 3629 #ifdef DEBUG_PK 3630 sshbuf_dump_data(prv->ed25519_sk, ED25519_SK_SZ, stderr); 3631 #endif 3632 } else { 3633 r = SSH_ERR_INVALID_FORMAT; 3634 goto out; 3635 } 3636 r = 0; 3637 if (keyp != NULL) { 3638 *keyp = prv; 3639 prv = NULL; 3640 } 3641 out: 3642 BIO_free(bio); 3643 EVP_PKEY_free(pk); 3644 RSA_free(rsa); 3645 EC_KEY_free(ecdsa); 3646 sshkey_free(prv); 3647 return r; 3648 } 3649 #endif /* WITH_OPENSSL */ 3650 3651 int 3652 sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type, 3653 const char *passphrase, struct sshkey **keyp, char **commentp) 3654 { 3655 int r = SSH_ERR_INTERNAL_ERROR; 3656 3657 if (keyp != NULL) 3658 *keyp = NULL; 3659 if (commentp != NULL) 3660 *commentp = NULL; 3661 3662 switch (type) { 3663 case KEY_XMSS: 3664 /* No fallback for new-format-only keys */ 3665 return sshkey_parse_private2(blob, type, passphrase, 3666 keyp, commentp); 3667 default: 3668 r = sshkey_parse_private2(blob, type, passphrase, keyp, 3669 commentp); 3670 /* Only fallback to PEM parser if a format error occurred. */ 3671 if (r != SSH_ERR_INVALID_FORMAT) 3672 return r; 3673 #ifdef WITH_OPENSSL 3674 return sshkey_parse_private_pem_fileblob(blob, type, 3675 passphrase, keyp); 3676 #else 3677 return SSH_ERR_INVALID_FORMAT; 3678 #endif /* WITH_OPENSSL */ 3679 } 3680 } 3681 3682 int 3683 sshkey_parse_private_fileblob(struct sshbuf *buffer, const char *passphrase, 3684 struct sshkey **keyp, char **commentp) 3685 { 3686 if (keyp != NULL) 3687 *keyp = NULL; 3688 if (commentp != NULL) 3689 *commentp = NULL; 3690 3691 return sshkey_parse_private_fileblob_type(buffer, KEY_UNSPEC, 3692 passphrase, keyp, commentp); 3693 } 3694 3695 void 3696 sshkey_sig_details_free(struct sshkey_sig_details *details) 3697 { 3698 freezero(details, sizeof(*details)); 3699 } 3700 3701 int 3702 sshkey_parse_pubkey_from_private_fileblob_type(struct sshbuf *blob, int type, 3703 struct sshkey **pubkeyp) 3704 { 3705 int r = SSH_ERR_INTERNAL_ERROR; 3706 3707 if (pubkeyp != NULL) 3708 *pubkeyp = NULL; 3709 /* only new-format private keys bundle a public key inside */ 3710 if ((r = sshkey_parse_private2_pubkey(blob, type, pubkeyp)) != 0) 3711 return r; 3712 return 0; 3713 } 3714 3715 #ifdef WITH_XMSS 3716 /* 3717 * serialize the key with the current state and forward the state 3718 * maxsign times. 3719 */ 3720 int 3721 sshkey_private_serialize_maxsign(struct sshkey *k, struct sshbuf *b, 3722 u_int32_t maxsign, int printerror) 3723 { 3724 int r, rupdate; 3725 3726 if (maxsign == 0 || 3727 sshkey_type_plain(k->type) != KEY_XMSS) 3728 return sshkey_private_serialize_opt(k, b, 3729 SSHKEY_SERIALIZE_DEFAULT); 3730 if ((r = sshkey_xmss_get_state(k, printerror)) != 0 || 3731 (r = sshkey_private_serialize_opt(k, b, 3732 SSHKEY_SERIALIZE_STATE)) != 0 || 3733 (r = sshkey_xmss_forward_state(k, maxsign)) != 0) 3734 goto out; 3735 r = 0; 3736 out: 3737 if ((rupdate = sshkey_xmss_update_state(k, printerror)) != 0) { 3738 if (r == 0) 3739 r = rupdate; 3740 } 3741 return r; 3742 } 3743 3744 u_int32_t 3745 sshkey_signatures_left(const struct sshkey *k) 3746 { 3747 if (sshkey_type_plain(k->type) == KEY_XMSS) 3748 return sshkey_xmss_signatures_left(k); 3749 return 0; 3750 } 3751 3752 int 3753 sshkey_enable_maxsign(struct sshkey *k, u_int32_t maxsign) 3754 { 3755 if (sshkey_type_plain(k->type) != KEY_XMSS) 3756 return SSH_ERR_INVALID_ARGUMENT; 3757 return sshkey_xmss_enable_maxsign(k, maxsign); 3758 } 3759 3760 int 3761 sshkey_set_filename(struct sshkey *k, const char *filename) 3762 { 3763 if (k == NULL) 3764 return SSH_ERR_INVALID_ARGUMENT; 3765 if (sshkey_type_plain(k->type) != KEY_XMSS) 3766 return 0; 3767 if (filename == NULL) 3768 return SSH_ERR_INVALID_ARGUMENT; 3769 if ((k->xmss_filename = strdup(filename)) == NULL) 3770 return SSH_ERR_ALLOC_FAIL; 3771 return 0; 3772 } 3773 #else 3774 int 3775 sshkey_private_serialize_maxsign(struct sshkey *k, struct sshbuf *b, 3776 u_int32_t maxsign, int printerror) 3777 { 3778 return sshkey_private_serialize_opt(k, b, SSHKEY_SERIALIZE_DEFAULT); 3779 } 3780 3781 u_int32_t 3782 sshkey_signatures_left(const struct sshkey *k) 3783 { 3784 return 0; 3785 } 3786 3787 int 3788 sshkey_enable_maxsign(struct sshkey *k, u_int32_t maxsign) 3789 { 3790 return SSH_ERR_INVALID_ARGUMENT; 3791 } 3792 3793 int 3794 sshkey_set_filename(struct sshkey *k, const char *filename) 3795 { 3796 if (k == NULL) 3797 return SSH_ERR_INVALID_ARGUMENT; 3798 return 0; 3799 } 3800 #endif /* WITH_XMSS */ 3801