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