1 /* $OpenBSD: ssh_api.c,v 1.7 2016/05/04 14:22:33 markus Exp $ */ 2 /* 3 * Copyright (c) 2012 Markus Friedl. All rights reserved. 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #include "ssh_api.h" 19 #include "compat.h" 20 #include "log.h" 21 #include "authfile.h" 22 #include "sshkey.h" 23 #include "misc.h" 24 #include "ssh2.h" 25 #include "version.h" 26 #include "myproposal.h" 27 #include "ssherr.h" 28 #include "sshbuf.h" 29 30 #include <string.h> 31 32 int _ssh_exchange_banner(struct ssh *); 33 int _ssh_send_banner(struct ssh *, char **); 34 int _ssh_read_banner(struct ssh *, char **); 35 int _ssh_order_hostkeyalgs(struct ssh *); 36 int _ssh_verify_host_key(struct sshkey *, struct ssh *); 37 struct sshkey *_ssh_host_public_key(int, int, struct ssh *); 38 struct sshkey *_ssh_host_private_key(int, int, struct ssh *); 39 int _ssh_host_key_sign(struct sshkey *, struct sshkey *, 40 u_char **, size_t *, const u_char *, size_t, const char *, u_int); 41 42 /* 43 * stubs for the server side implementation of kex. 44 * disable privsep so our stubs will never be called. 45 */ 46 int use_privsep = 0; 47 int mm_sshkey_sign(struct sshkey *, u_char **, u_int *, 48 u_char *, u_int, char *, u_int); 49 DH *mm_choose_dh(int, int, int); 50 51 /* Define these two variables here so that they are part of the library */ 52 u_char *session_id2 = NULL; 53 u_int session_id2_len = 0; 54 55 int 56 mm_sshkey_sign(struct sshkey *key, u_char **sigp, u_int *lenp, 57 u_char *data, u_int datalen, char *alg, u_int compat) 58 { 59 return (-1); 60 } 61 62 DH * 63 mm_choose_dh(int min, int nbits, int max) 64 { 65 return (NULL); 66 } 67 68 /* API */ 69 70 int 71 ssh_init(struct ssh **sshp, int is_server, struct kex_params *kex_params) 72 { 73 char *myproposal[PROPOSAL_MAX] = { KEX_CLIENT }; 74 struct ssh *ssh; 75 char **proposal; 76 static int called; 77 int r; 78 79 if (!called) { 80 OpenSSL_add_all_algorithms(); 81 called = 1; 82 } 83 84 if ((ssh = ssh_packet_set_connection(NULL, -1, -1)) == NULL) 85 return SSH_ERR_ALLOC_FAIL; 86 if (is_server) 87 ssh_packet_set_server(ssh); 88 89 /* Initialize key exchange */ 90 proposal = kex_params ? kex_params->proposal : myproposal; 91 if ((r = kex_new(ssh, proposal, &ssh->kex)) != 0) { 92 ssh_free(ssh); 93 return r; 94 } 95 ssh->kex->server = is_server; 96 if (is_server) { 97 #ifdef WITH_OPENSSL 98 ssh->kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server; 99 ssh->kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server; 100 ssh->kex->kex[KEX_DH_GRP14_SHA256] = kexdh_server; 101 ssh->kex->kex[KEX_DH_GRP16_SHA512] = kexdh_server; 102 ssh->kex->kex[KEX_DH_GRP18_SHA512] = kexdh_server; 103 ssh->kex->kex[KEX_DH_GEX_SHA1] = kexgex_server; 104 ssh->kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; 105 ssh->kex->kex[KEX_ECDH_SHA2] = kexecdh_server; 106 #endif /* WITH_OPENSSL */ 107 ssh->kex->kex[KEX_C25519_SHA256] = kexc25519_server; 108 ssh->kex->load_host_public_key=&_ssh_host_public_key; 109 ssh->kex->load_host_private_key=&_ssh_host_private_key; 110 ssh->kex->sign=&_ssh_host_key_sign; 111 } else { 112 #ifdef WITH_OPENSSL 113 ssh->kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client; 114 ssh->kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client; 115 ssh->kex->kex[KEX_DH_GRP14_SHA256] = kexdh_client; 116 ssh->kex->kex[KEX_DH_GRP16_SHA512] = kexdh_client; 117 ssh->kex->kex[KEX_DH_GRP18_SHA512] = kexdh_client; 118 ssh->kex->kex[KEX_DH_GEX_SHA1] = kexgex_client; 119 ssh->kex->kex[KEX_DH_GEX_SHA256] = kexgex_client; 120 ssh->kex->kex[KEX_ECDH_SHA2] = kexecdh_client; 121 #endif /* WITH_OPENSSL */ 122 ssh->kex->kex[KEX_C25519_SHA256] = kexc25519_client; 123 ssh->kex->verify_host_key =&_ssh_verify_host_key; 124 } 125 *sshp = ssh; 126 return 0; 127 } 128 129 void 130 ssh_free(struct ssh *ssh) 131 { 132 struct key_entry *k; 133 134 ssh_packet_close(ssh); 135 /* 136 * we've only created the public keys variants in case we 137 * are a acting as a server. 138 */ 139 while ((k = TAILQ_FIRST(&ssh->public_keys)) != NULL) { 140 TAILQ_REMOVE(&ssh->public_keys, k, next); 141 if (ssh->kex && ssh->kex->server) 142 sshkey_free(k->key); 143 free(k); 144 } 145 while ((k = TAILQ_FIRST(&ssh->private_keys)) != NULL) { 146 TAILQ_REMOVE(&ssh->private_keys, k, next); 147 free(k); 148 } 149 if (ssh->kex) 150 kex_free(ssh->kex); 151 free(ssh); 152 } 153 154 void 155 ssh_set_app_data(struct ssh *ssh, void *app_data) 156 { 157 ssh->app_data = app_data; 158 } 159 160 void * 161 ssh_get_app_data(struct ssh *ssh) 162 { 163 return ssh->app_data; 164 } 165 166 /* Returns < 0 on error, 0 otherwise */ 167 int 168 ssh_add_hostkey(struct ssh *ssh, struct sshkey *key) 169 { 170 struct sshkey *pubkey = NULL; 171 struct key_entry *k = NULL, *k_prv = NULL; 172 int r; 173 174 if (ssh->kex->server) { 175 if ((r = sshkey_from_private(key, &pubkey)) != 0) 176 return r; 177 if ((k = malloc(sizeof(*k))) == NULL || 178 (k_prv = malloc(sizeof(*k_prv))) == NULL) { 179 free(k); 180 sshkey_free(pubkey); 181 return SSH_ERR_ALLOC_FAIL; 182 } 183 k_prv->key = key; 184 TAILQ_INSERT_TAIL(&ssh->private_keys, k_prv, next); 185 186 /* add the public key, too */ 187 k->key = pubkey; 188 TAILQ_INSERT_TAIL(&ssh->public_keys, k, next); 189 r = 0; 190 } else { 191 if ((k = malloc(sizeof(*k))) == NULL) 192 return SSH_ERR_ALLOC_FAIL; 193 k->key = key; 194 TAILQ_INSERT_TAIL(&ssh->public_keys, k, next); 195 r = 0; 196 } 197 198 return r; 199 } 200 201 int 202 ssh_set_verify_host_key_callback(struct ssh *ssh, 203 int (*cb)(struct sshkey *, struct ssh *)) 204 { 205 if (cb == NULL || ssh->kex == NULL) 206 return SSH_ERR_INVALID_ARGUMENT; 207 208 ssh->kex->verify_host_key = cb; 209 210 return 0; 211 } 212 213 int 214 ssh_input_append(struct ssh *ssh, const u_char *data, size_t len) 215 { 216 return sshbuf_put(ssh_packet_get_input(ssh), data, len); 217 } 218 219 int 220 ssh_packet_next(struct ssh *ssh, u_char *typep) 221 { 222 int r; 223 u_int32_t seqnr; 224 u_char type; 225 226 /* 227 * Try to read a packet. Return SSH_MSG_NONE if no packet or not 228 * enough data. 229 */ 230 *typep = SSH_MSG_NONE; 231 if (ssh->kex->client_version_string == NULL || 232 ssh->kex->server_version_string == NULL) 233 return _ssh_exchange_banner(ssh); 234 /* 235 * If we enough data and a dispatch function then 236 * call the function and get the next packet. 237 * Otherwise return the packet type to the caller so it 238 * can decide how to go on. 239 * 240 * We will only call the dispatch function for: 241 * 20-29 Algorithm negotiation 242 * 30-49 Key exchange method specific (numbers can be reused for 243 * different authentication methods) 244 */ 245 for (;;) { 246 if ((r = ssh_packet_read_poll2(ssh, &type, &seqnr)) != 0) 247 return r; 248 if (type > 0 && type < DISPATCH_MAX && 249 type >= SSH2_MSG_KEXINIT && type <= SSH2_MSG_TRANSPORT_MAX && 250 ssh->dispatch[type] != NULL) { 251 if ((r = (*ssh->dispatch[type])(type, seqnr, ssh)) != 0) 252 return r; 253 } else { 254 *typep = type; 255 return 0; 256 } 257 } 258 } 259 260 const u_char * 261 ssh_packet_payload(struct ssh *ssh, size_t *lenp) 262 { 263 return sshpkt_ptr(ssh, lenp); 264 } 265 266 int 267 ssh_packet_put(struct ssh *ssh, int type, const u_char *data, size_t len) 268 { 269 int r; 270 271 if ((r = sshpkt_start(ssh, type)) != 0 || 272 (r = sshpkt_put(ssh, data, len)) != 0 || 273 (r = sshpkt_send(ssh)) != 0) 274 return r; 275 return 0; 276 } 277 278 const u_char * 279 ssh_output_ptr(struct ssh *ssh, size_t *len) 280 { 281 struct sshbuf *output = ssh_packet_get_output(ssh); 282 283 *len = sshbuf_len(output); 284 return sshbuf_ptr(output); 285 } 286 287 int 288 ssh_output_consume(struct ssh *ssh, size_t len) 289 { 290 return sshbuf_consume(ssh_packet_get_output(ssh), len); 291 } 292 293 int 294 ssh_output_space(struct ssh *ssh, size_t len) 295 { 296 return (0 == sshbuf_check_reserve(ssh_packet_get_output(ssh), len)); 297 } 298 299 int 300 ssh_input_space(struct ssh *ssh, size_t len) 301 { 302 return (0 == sshbuf_check_reserve(ssh_packet_get_input(ssh), len)); 303 } 304 305 /* Read other side's version identification. */ 306 int 307 _ssh_read_banner(struct ssh *ssh, char **bannerp) 308 { 309 struct sshbuf *input; 310 const char *s; 311 char buf[256], remote_version[256]; /* must be same size! */ 312 const char *mismatch = "Protocol mismatch.\r\n"; 313 int r, remote_major, remote_minor; 314 size_t i, n, j, len; 315 316 *bannerp = NULL; 317 input = ssh_packet_get_input(ssh); 318 len = sshbuf_len(input); 319 s = (const char *)sshbuf_ptr(input); 320 for (j = n = 0;;) { 321 for (i = 0; i < sizeof(buf) - 1; i++) { 322 if (j >= len) 323 return (0); 324 buf[i] = s[j++]; 325 if (buf[i] == '\r') { 326 buf[i] = '\n'; 327 buf[i + 1] = 0; 328 continue; /**XXX wait for \n */ 329 } 330 if (buf[i] == '\n') { 331 buf[i + 1] = 0; 332 break; 333 } 334 } 335 buf[sizeof(buf) - 1] = 0; 336 if (strncmp(buf, "SSH-", 4) == 0) 337 break; 338 debug("ssh_exchange_identification: %s", buf); 339 if (ssh->kex->server || ++n > 65536) { 340 if ((r = sshbuf_put(ssh_packet_get_output(ssh), 341 mismatch, strlen(mismatch))) != 0) 342 return r; 343 return SSH_ERR_NO_PROTOCOL_VERSION; 344 } 345 } 346 if ((r = sshbuf_consume(input, j)) != 0) 347 return r; 348 349 /* 350 * Check that the versions match. In future this might accept 351 * several versions and set appropriate flags to handle them. 352 */ 353 if (sscanf(buf, "SSH-%d.%d-%[^\n]\n", 354 &remote_major, &remote_minor, remote_version) != 3) 355 return SSH_ERR_INVALID_FORMAT; 356 debug("Remote protocol version %d.%d, remote software version %.100s", 357 remote_major, remote_minor, remote_version); 358 359 ssh->compat = compat_datafellows(remote_version); 360 if (remote_major == 1 && remote_minor == 99) { 361 remote_major = 2; 362 remote_minor = 0; 363 } 364 if (remote_major != 2) 365 return SSH_ERR_PROTOCOL_MISMATCH; 366 enable_compat20(); 367 chop(buf); 368 debug("Remote version string %.100s", buf); 369 if ((*bannerp = strdup(buf)) == NULL) 370 return SSH_ERR_ALLOC_FAIL; 371 return 0; 372 } 373 374 /* Send our own protocol version identification. */ 375 int 376 _ssh_send_banner(struct ssh *ssh, char **bannerp) 377 { 378 char buf[256]; 379 int r; 380 381 snprintf(buf, sizeof buf, "SSH-2.0-%.100s\r\n", SSH_VERSION); 382 if ((r = sshbuf_put(ssh_packet_get_output(ssh), buf, strlen(buf))) != 0) 383 return r; 384 chop(buf); 385 debug("Local version string %.100s", buf); 386 if ((*bannerp = strdup(buf)) == NULL) 387 return SSH_ERR_ALLOC_FAIL; 388 return 0; 389 } 390 391 int 392 _ssh_exchange_banner(struct ssh *ssh) 393 { 394 struct kex *kex = ssh->kex; 395 int r; 396 397 /* 398 * if _ssh_read_banner() cannot parse a full version string 399 * it will return NULL and we end up calling it again. 400 */ 401 402 r = 0; 403 if (kex->server) { 404 if (kex->server_version_string == NULL) 405 r = _ssh_send_banner(ssh, &kex->server_version_string); 406 if (r == 0 && 407 kex->server_version_string != NULL && 408 kex->client_version_string == NULL) 409 r = _ssh_read_banner(ssh, &kex->client_version_string); 410 } else { 411 if (kex->server_version_string == NULL) 412 r = _ssh_read_banner(ssh, &kex->server_version_string); 413 if (r == 0 && 414 kex->server_version_string != NULL && 415 kex->client_version_string == NULL) 416 r = _ssh_send_banner(ssh, &kex->client_version_string); 417 } 418 if (r != 0) 419 return r; 420 /* start initial kex as soon as we have exchanged the banners */ 421 if (kex->server_version_string != NULL && 422 kex->client_version_string != NULL) { 423 if ((r = _ssh_order_hostkeyalgs(ssh)) != 0 || 424 (r = kex_send_kexinit(ssh)) != 0) 425 return r; 426 } 427 return 0; 428 } 429 430 struct sshkey * 431 _ssh_host_public_key(int type, int nid, struct ssh *ssh) 432 { 433 struct key_entry *k; 434 435 debug3("%s: need %d", __func__, type); 436 TAILQ_FOREACH(k, &ssh->public_keys, next) { 437 debug3("%s: check %s", __func__, sshkey_type(k->key)); 438 if (k->key->type == type && 439 (type != KEY_ECDSA || k->key->ecdsa_nid == nid)) 440 return (k->key); 441 } 442 return (NULL); 443 } 444 445 struct sshkey * 446 _ssh_host_private_key(int type, int nid, struct ssh *ssh) 447 { 448 struct key_entry *k; 449 450 debug3("%s: need %d", __func__, type); 451 TAILQ_FOREACH(k, &ssh->private_keys, next) { 452 debug3("%s: check %s", __func__, sshkey_type(k->key)); 453 if (k->key->type == type && 454 (type != KEY_ECDSA || k->key->ecdsa_nid == nid)) 455 return (k->key); 456 } 457 return (NULL); 458 } 459 460 int 461 _ssh_verify_host_key(struct sshkey *hostkey, struct ssh *ssh) 462 { 463 struct key_entry *k; 464 465 debug3("%s: need %s", __func__, sshkey_type(hostkey)); 466 TAILQ_FOREACH(k, &ssh->public_keys, next) { 467 debug3("%s: check %s", __func__, sshkey_type(k->key)); 468 if (sshkey_equal_public(hostkey, k->key)) 469 return (0); /* ok */ 470 } 471 return (-1); /* failed */ 472 } 473 474 /* offer hostkey algorithms in kexinit depending on registered keys */ 475 int 476 _ssh_order_hostkeyalgs(struct ssh *ssh) 477 { 478 struct key_entry *k; 479 char *orig, *avail, *oavail = NULL, *alg, *replace = NULL; 480 char **proposal; 481 size_t maxlen; 482 int ktype, r; 483 484 /* XXX we de-serialize ssh->kex->my, modify it, and change it */ 485 if ((r = kex_buf2prop(ssh->kex->my, NULL, &proposal)) != 0) 486 return r; 487 orig = proposal[PROPOSAL_SERVER_HOST_KEY_ALGS]; 488 if ((oavail = avail = strdup(orig)) == NULL) { 489 r = SSH_ERR_ALLOC_FAIL; 490 goto out; 491 } 492 maxlen = strlen(avail) + 1; 493 if ((replace = calloc(1, maxlen)) == NULL) { 494 r = SSH_ERR_ALLOC_FAIL; 495 goto out; 496 } 497 *replace = '\0'; 498 while ((alg = strsep(&avail, ",")) && *alg != '\0') { 499 if ((ktype = sshkey_type_from_name(alg)) == KEY_UNSPEC) 500 continue; 501 TAILQ_FOREACH(k, &ssh->public_keys, next) { 502 if (k->key->type == ktype || 503 (sshkey_is_cert(k->key) && k->key->type == 504 sshkey_type_plain(ktype))) { 505 if (*replace != '\0') 506 strlcat(replace, ",", maxlen); 507 strlcat(replace, alg, maxlen); 508 break; 509 } 510 } 511 } 512 if (*replace != '\0') { 513 debug2("%s: orig/%d %s", __func__, ssh->kex->server, orig); 514 debug2("%s: replace/%d %s", __func__, ssh->kex->server, replace); 515 free(orig); 516 proposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = replace; 517 replace = NULL; /* owned by proposal */ 518 r = kex_prop2buf(ssh->kex->my, proposal); 519 } 520 out: 521 free(oavail); 522 free(replace); 523 kex_prop_free(proposal); 524 return r; 525 } 526 527 int 528 _ssh_host_key_sign(struct sshkey *privkey, struct sshkey *pubkey, 529 u_char **signature, size_t *slen, const u_char *data, size_t dlen, 530 const char *alg, u_int compat) 531 { 532 return sshkey_sign(privkey, signature, slen, data, dlen, alg, compat); 533 } 534