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