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