summaryrefslogtreecommitdiff
path: root/sshd.c
diff options
context:
space:
mode:
authorBen Lindstrom <mouring@eviladmin.org>2001-04-04 01:56:17 +0000
committerBen Lindstrom <mouring@eviladmin.org>2001-04-04 01:56:17 +0000
commit20d7c7b02c92c28007dba8b08e617a415146d1df (patch)
tree8b5258b1065f6ad079d7410c3a29562903f128bb /sshd.c
parent86ebcb6cf55ea296a7921d157afdc03c07102933 (diff)
- markus@cvs.openbsd.org 2001/04/03 19:53:29
[dh.c dh.h kex.c kex.h sshconnect2.c sshd.c] move kex to kex*.c, used dispatch_set() callbacks for kex. should make rekeying easier.
Diffstat (limited to 'sshd.c')
-rw-r--r--sshd.c359
1 files changed, 10 insertions, 349 deletions
diff --git a/sshd.c b/sshd.c
index b5e2d0f6f..c54675962 100644
--- a/sshd.c
+++ b/sshd.c
@@ -40,7 +40,7 @@
40 */ 40 */
41 41
42#include "includes.h" 42#include "includes.h"
43RCSID("$OpenBSD: sshd.c,v 1.185 2001/03/29 23:42:01 djm Exp $"); 43RCSID("$OpenBSD: sshd.c,v 1.186 2001/04/03 19:53:29 markus Exp $");
44 44
45#include <openssl/dh.h> 45#include <openssl/dh.h>
46#include <openssl/bn.h> 46#include <openssl/bn.h>
@@ -70,6 +70,7 @@ RCSID("$OpenBSD: sshd.c,v 1.185 2001/03/29 23:42:01 djm Exp $");
70#include "canohost.h" 70#include "canohost.h"
71#include "auth.h" 71#include "auth.h"
72#include "misc.h" 72#include "misc.h"
73#include "dispatch.h"
73 74
74#ifdef LIBWRAP 75#ifdef LIBWRAP
75#include <tcpd.h> 76#include <tcpd.h>
@@ -1407,14 +1408,7 @@ do_ssh1_kex(void)
1407void 1408void
1408do_ssh2_kex(void) 1409do_ssh2_kex(void)
1409{ 1410{
1410 Buffer *server_kexinit;
1411 Buffer *client_kexinit;
1412 int payload_len;
1413 int i;
1414 Kex *kex; 1411 Kex *kex;
1415 char *cprop[PROPOSAL_MAX];
1416
1417/* KEXINIT */
1418 1412
1419 if (options.ciphers != NULL) { 1413 if (options.ciphers != NULL) {
1420 myproposal[PROPOSAL_ENC_ALGS_CTOS] = 1414 myproposal[PROPOSAL_ENC_ALGS_CTOS] =
@@ -1431,36 +1425,14 @@ do_ssh2_kex(void)
1431 } 1425 }
1432 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = list_hostkey_types(); 1426 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = list_hostkey_types();
1433 1427
1434 server_kexinit = kex_init(myproposal); 1428 kex = kex_start(myproposal);
1435 client_kexinit = xmalloc(sizeof(*client_kexinit)); 1429 kex->server = 1;
1436 buffer_init(client_kexinit); 1430 kex->client_version_string=client_version_string;
1437 1431 kex->server_version_string=server_version_string;
1438 /* algorithm negotiation */ 1432 kex->load_host_key=&get_hostkey_by_type;
1439 kex_exchange_kexinit(server_kexinit, client_kexinit, cprop);
1440 kex = kex_choose_conf(cprop, myproposal, 1);
1441 for (i = 0; i < PROPOSAL_MAX; i++)
1442 xfree(cprop[i]);
1443
1444 switch (kex->kex_type) {
1445 case DH_GRP1_SHA1:
1446 ssh_dh1_server(kex, client_kexinit, server_kexinit);
1447 break;
1448 case DH_GEX_SHA1:
1449 ssh_dhgex_server(kex, client_kexinit, server_kexinit);
1450 break;
1451 default:
1452 fatal("Unsupported key exchange %d", kex->kex_type);
1453 }
1454
1455 debug("send SSH2_MSG_NEWKEYS.");
1456 packet_start(SSH2_MSG_NEWKEYS);
1457 packet_send();
1458 packet_write_wait();
1459 debug("done: send SSH2_MSG_NEWKEYS.");
1460 1433
1461 debug("Wait SSH2_MSG_NEWKEYS."); 1434 /* start key exchange */
1462 packet_read_expect(&payload_len, SSH2_MSG_NEWKEYS); 1435 dispatch_run(DISPATCH_BLOCK, &kex->newkeys, kex);
1463 debug("GOT SSH2_MSG_NEWKEYS.");
1464 1436
1465#ifdef DEBUG_KEXDH 1437#ifdef DEBUG_KEXDH
1466 /* send 1st encrypted/maced/compressed message */ 1438 /* send 1st encrypted/maced/compressed message */
@@ -1469,316 +1441,5 @@ do_ssh2_kex(void)
1469 packet_send(); 1441 packet_send();
1470 packet_write_wait(); 1442 packet_write_wait();
1471#endif 1443#endif
1472 1444 debug("KEX done");
1473 debug("done: KEX2.");
1474}
1475
1476/*
1477 * SSH2 key exchange
1478 */
1479
1480/* diffie-hellman-group1-sha1 */
1481
1482void
1483ssh_dh1_server(Kex *kex, Buffer *client_kexinit, Buffer *server_kexinit)
1484{
1485#ifdef DEBUG_KEXDH
1486 int i;
1487#endif
1488 int payload_len, dlen;
1489 int slen;
1490 u_char *signature = NULL;
1491 u_char *server_host_key_blob = NULL;
1492 u_int sbloblen;
1493 u_int klen, kout;
1494 u_char *kbuf;
1495 u_char *hash;
1496 BIGNUM *shared_secret = 0;
1497 DH *dh;
1498 BIGNUM *dh_client_pub = 0;
1499 Key *hostkey;
1500
1501 hostkey = get_hostkey_by_type(kex->hostkey_type);
1502 if (hostkey == NULL)
1503 fatal("Unsupported hostkey type %d", kex->hostkey_type);
1504
1505/* KEXDH */
1506 /* generate DH key */
1507 dh = dh_new_group1(); /* XXX depends on 'kex' */
1508 dh_gen_key(dh, kex->we_need * 8);
1509
1510 debug("Wait SSH2_MSG_KEXDH_INIT.");
1511 packet_read_expect(&payload_len, SSH2_MSG_KEXDH_INIT);
1512
1513 /* key, cert */
1514 dh_client_pub = BN_new();
1515 if (dh_client_pub == NULL)
1516 fatal("dh_client_pub == NULL");
1517 packet_get_bignum2(dh_client_pub, &dlen);
1518
1519#ifdef DEBUG_KEXDH
1520 fprintf(stderr, "\ndh_client_pub= ");
1521 BN_print_fp(stderr, dh_client_pub);
1522 fprintf(stderr, "\n");
1523 debug("bits %d", BN_num_bits(dh_client_pub));
1524#endif
1525
1526#ifdef DEBUG_KEXDH
1527 fprintf(stderr, "\np= ");
1528 BN_print_fp(stderr, dh->p);
1529 fprintf(stderr, "\ng= ");
1530 bn_print(dh->g);
1531 fprintf(stderr, "\npub= ");
1532 BN_print_fp(stderr, dh->pub_key);
1533 fprintf(stderr, "\n");
1534 DHparams_print_fp(stderr, dh);
1535#endif
1536 if (!dh_pub_is_valid(dh, dh_client_pub))
1537 packet_disconnect("bad client public DH value");
1538
1539 klen = DH_size(dh);
1540 kbuf = xmalloc(klen);
1541 kout = DH_compute_key(kbuf, dh_client_pub, dh);
1542
1543#ifdef DEBUG_KEXDH
1544 debug("shared secret: len %d/%d", klen, kout);
1545 fprintf(stderr, "shared secret == ");
1546 for (i = 0; i< kout; i++)
1547 fprintf(stderr, "%02x", (kbuf[i])&0xff);
1548 fprintf(stderr, "\n");
1549#endif
1550 shared_secret = BN_new();
1551
1552 BN_bin2bn(kbuf, kout, shared_secret);
1553 memset(kbuf, 0, klen);
1554 xfree(kbuf);
1555
1556 /* XXX precompute? */
1557 key_to_blob(hostkey, &server_host_key_blob, &sbloblen);
1558
1559 /* calc H */ /* XXX depends on 'kex' */
1560 hash = kex_hash(
1561 client_version_string,
1562 server_version_string,
1563 buffer_ptr(client_kexinit), buffer_len(client_kexinit),
1564 buffer_ptr(server_kexinit), buffer_len(server_kexinit),
1565 (char *)server_host_key_blob, sbloblen,
1566 dh_client_pub,
1567 dh->pub_key,
1568 shared_secret
1569 );
1570 buffer_free(client_kexinit);
1571 buffer_free(server_kexinit);
1572 xfree(client_kexinit);
1573 xfree(server_kexinit);
1574 BN_free(dh_client_pub);
1575#ifdef DEBUG_KEXDH
1576 fprintf(stderr, "hash == ");
1577 for (i = 0; i< 20; i++)
1578 fprintf(stderr, "%02x", (hash[i])&0xff);
1579 fprintf(stderr, "\n");
1580#endif
1581 /* save session id := H */
1582 /* XXX hashlen depends on KEX */
1583 session_id2_len = 20;
1584 session_id2 = xmalloc(session_id2_len);
1585 memcpy(session_id2, hash, session_id2_len);
1586
1587 /* sign H */
1588 /* XXX hashlen depends on KEX */
1589 key_sign(hostkey, &signature, &slen, hash, 20);
1590
1591 destroy_sensitive_data();
1592
1593 /* send server hostkey, DH pubkey 'f' and singed H */
1594 packet_start(SSH2_MSG_KEXDH_REPLY);
1595 packet_put_string((char *)server_host_key_blob, sbloblen);
1596 packet_put_bignum2(dh->pub_key); /* f */
1597 packet_put_string((char *)signature, slen);
1598 packet_send();
1599 xfree(signature);
1600 xfree(server_host_key_blob);
1601 packet_write_wait();
1602
1603 kex_derive_keys(kex, hash, shared_secret);
1604 BN_clear_free(shared_secret);
1605 packet_set_kex(kex);
1606
1607 /* have keys, free DH */
1608 DH_free(dh);
1609}
1610
1611/* diffie-hellman-group-exchange-sha1 */
1612
1613void
1614ssh_dhgex_server(Kex *kex, Buffer *client_kexinit, Buffer *server_kexinit)
1615{
1616#ifdef DEBUG_KEXDH
1617 int i;
1618#endif
1619 int payload_len, dlen;
1620 int slen, nbits, type, min, max;
1621 u_char *signature = NULL;
1622 u_char *server_host_key_blob = NULL;
1623 u_int sbloblen;
1624 u_int klen, kout;
1625 u_char *kbuf;
1626 u_char *hash;
1627 BIGNUM *shared_secret = 0;
1628 DH *dh;
1629 BIGNUM *dh_client_pub = 0;
1630 Key *hostkey;
1631
1632 hostkey = get_hostkey_by_type(kex->hostkey_type);
1633 if (hostkey == NULL)
1634 fatal("Unsupported hostkey type %d", kex->hostkey_type);
1635
1636/* KEXDHGEX */
1637 debug("Wait SSH2_MSG_KEX_DH_GEX_REQUEST.");
1638 type = packet_read(&payload_len);
1639 if (type != SSH2_MSG_KEX_DH_GEX_REQUEST_OLD &&
1640 type != SSH2_MSG_KEX_DH_GEX_REQUEST)
1641 packet_disconnect("Protocol error: expected type %d or %d, got %d",
1642 SSH2_MSG_KEX_DH_GEX_REQUEST_OLD,
1643 SSH2_MSG_KEX_DH_GEX_REQUEST,
1644 type);
1645 if (type == SSH2_MSG_KEX_DH_GEX_REQUEST_OLD) {
1646 nbits = packet_get_int();
1647 min = DH_GRP_MIN;
1648 max = DH_GRP_MAX;
1649 } else {
1650 min = packet_get_int();
1651 nbits = packet_get_int();
1652 max = packet_get_int();
1653
1654 min = MAX(DH_GRP_MIN, min);
1655 max = MIN(DH_GRP_MAX, max);
1656 }
1657
1658 if (max < min || nbits < min || max < nbits)
1659 fatal("DH_GEX_REQUEST, bad parameters: %d !< %d !< %d",
1660 min, nbits, max);
1661
1662 dh = choose_dh(min, nbits, max);
1663 if (dh == NULL)
1664 packet_disconnect("Protocol error: no matching DH grp found");
1665
1666 debug("Sending SSH2_MSG_KEX_DH_GEX_GROUP.");
1667 packet_start(SSH2_MSG_KEX_DH_GEX_GROUP);
1668 packet_put_bignum2(dh->p);
1669 packet_put_bignum2(dh->g);
1670 packet_send();
1671 packet_write_wait();
1672
1673 /* Compute our exchange value in parallel with the client */
1674
1675 dh_gen_key(dh, kex->we_need * 8);
1676
1677 debug("Wait SSH2_MSG_KEX_DH_GEX_INIT.");
1678 packet_read_expect(&payload_len, SSH2_MSG_KEX_DH_GEX_INIT);
1679
1680 /* key, cert */
1681 dh_client_pub = BN_new();
1682 if (dh_client_pub == NULL)
1683 fatal("dh_client_pub == NULL");
1684 packet_get_bignum2(dh_client_pub, &dlen);
1685
1686#ifdef DEBUG_KEXDH
1687 fprintf(stderr, "\ndh_client_pub= ");
1688 BN_print_fp(stderr, dh_client_pub);
1689 fprintf(stderr, "\n");
1690 debug("bits %d", BN_num_bits(dh_client_pub));
1691#endif
1692
1693#ifdef DEBUG_KEXDH
1694 fprintf(stderr, "\np= ");
1695 BN_print_fp(stderr, dh->p);
1696 fprintf(stderr, "\ng= ");
1697 bn_print(dh->g);
1698 fprintf(stderr, "\npub= ");
1699 BN_print_fp(stderr, dh->pub_key);
1700 fprintf(stderr, "\n");
1701 DHparams_print_fp(stderr, dh);
1702#endif
1703 if (!dh_pub_is_valid(dh, dh_client_pub))
1704 packet_disconnect("bad client public DH value");
1705
1706 klen = DH_size(dh);
1707 kbuf = xmalloc(klen);
1708 kout = DH_compute_key(kbuf, dh_client_pub, dh);
1709
1710#ifdef DEBUG_KEXDH
1711 debug("shared secret: len %d/%d", klen, kout);
1712 fprintf(stderr, "shared secret == ");
1713 for (i = 0; i< kout; i++)
1714 fprintf(stderr, "%02x", (kbuf[i])&0xff);
1715 fprintf(stderr, "\n");
1716#endif
1717 shared_secret = BN_new();
1718
1719 BN_bin2bn(kbuf, kout, shared_secret);
1720 memset(kbuf, 0, klen);
1721 xfree(kbuf);
1722
1723 /* XXX precompute? */
1724 key_to_blob(hostkey, &server_host_key_blob, &sbloblen);
1725
1726 if (type == SSH2_MSG_KEX_DH_GEX_REQUEST_OLD) {
1727 /* These values are not included in the hash */
1728 min = -1;
1729 max = -1;
1730 }
1731
1732 /* calc H */ /* XXX depends on 'kex' */
1733 hash = kex_hash_gex(
1734 client_version_string,
1735 server_version_string,
1736 buffer_ptr(client_kexinit), buffer_len(client_kexinit),
1737 buffer_ptr(server_kexinit), buffer_len(server_kexinit),
1738 (char *)server_host_key_blob, sbloblen,
1739 min, nbits, max,
1740 dh->p, dh->g,
1741 dh_client_pub,
1742 dh->pub_key,
1743 shared_secret
1744 );
1745 buffer_free(client_kexinit);
1746 buffer_free(server_kexinit);
1747 xfree(client_kexinit);
1748 xfree(server_kexinit);
1749 BN_free(dh_client_pub);
1750#ifdef DEBUG_KEXDH
1751 fprintf(stderr, "hash == ");
1752 for (i = 0; i< 20; i++)
1753 fprintf(stderr, "%02x", (hash[i])&0xff);
1754 fprintf(stderr, "\n");
1755#endif
1756 /* save session id := H */
1757 /* XXX hashlen depends on KEX */
1758 session_id2_len = 20;
1759 session_id2 = xmalloc(session_id2_len);
1760 memcpy(session_id2, hash, session_id2_len);
1761
1762 /* sign H */
1763 /* XXX hashlen depends on KEX */
1764 key_sign(hostkey, &signature, &slen, hash, 20);
1765
1766 destroy_sensitive_data();
1767
1768 /* send server hostkey, DH pubkey 'f' and singed H */
1769 packet_start(SSH2_MSG_KEX_DH_GEX_REPLY);
1770 packet_put_string((char *)server_host_key_blob, sbloblen);
1771 packet_put_bignum2(dh->pub_key); /* f */
1772 packet_put_string((char *)signature, slen);
1773 packet_send();
1774 xfree(signature);
1775 xfree(server_host_key_blob);
1776 packet_write_wait();
1777
1778 kex_derive_keys(kex, hash, shared_secret);
1779 BN_clear_free(shared_secret);
1780 packet_set_kex(kex);
1781
1782 /* have keys, free DH */
1783 DH_free(dh);
1784} 1445}