diff options
-rw-r--r-- | bufbn.c | 42 | ||||
-rw-r--r-- | buffer.h | 6 | ||||
-rw-r--r-- | packet.c | 149 | ||||
-rw-r--r-- | packet.h | 5 |
4 files changed, 4 insertions, 198 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: bufbn.c,v 1.12 2014/04/30 05:29:56 djm Exp $ */ | 1 | /* $OpenBSD: bufbn.c,v 1.13 2017/04/30 23:23:54 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Copyright (c) 2012 Damien Miller <djm@mindrot.org> | 4 | * Copyright (c) 2012 Damien Miller <djm@mindrot.org> |
@@ -28,46 +28,6 @@ | |||
28 | #include "log.h" | 28 | #include "log.h" |
29 | #include "ssherr.h" | 29 | #include "ssherr.h" |
30 | 30 | ||
31 | #ifdef WITH_SSH1 | ||
32 | int | ||
33 | buffer_put_bignum_ret(Buffer *buffer, const BIGNUM *value) | ||
34 | { | ||
35 | int ret; | ||
36 | |||
37 | if ((ret = sshbuf_put_bignum1(buffer, value)) != 0) { | ||
38 | error("%s: %s", __func__, ssh_err(ret)); | ||
39 | return -1; | ||
40 | } | ||
41 | return 0; | ||
42 | } | ||
43 | |||
44 | void | ||
45 | buffer_put_bignum(Buffer *buffer, const BIGNUM *value) | ||
46 | { | ||
47 | if (buffer_put_bignum_ret(buffer, value) == -1) | ||
48 | fatal("%s: buffer error", __func__); | ||
49 | } | ||
50 | |||
51 | int | ||
52 | buffer_get_bignum_ret(Buffer *buffer, BIGNUM *value) | ||
53 | { | ||
54 | int ret; | ||
55 | |||
56 | if ((ret = sshbuf_get_bignum1(buffer, value)) != 0) { | ||
57 | error("%s: %s", __func__, ssh_err(ret)); | ||
58 | return -1; | ||
59 | } | ||
60 | return 0; | ||
61 | } | ||
62 | |||
63 | void | ||
64 | buffer_get_bignum(Buffer *buffer, BIGNUM *value) | ||
65 | { | ||
66 | if (buffer_get_bignum_ret(buffer, value) == -1) | ||
67 | fatal("%s: buffer error", __func__); | ||
68 | } | ||
69 | #endif /* WITH_SSH1 */ | ||
70 | |||
71 | int | 31 | int |
72 | buffer_put_bignum2_ret(Buffer *buffer, const BIGNUM *value) | 32 | buffer_put_bignum2_ret(Buffer *buffer, const BIGNUM *value) |
73 | { | 33 | { |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: buffer.h,v 1.25 2014/04/30 05:29:56 djm Exp $ */ | 1 | /* $OpenBSD: buffer.h,v 1.26 2017/04/30 23:23:54 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Copyright (c) 2012 Damien Miller <djm@mindrot.org> | 4 | * Copyright (c) 2012 Damien Miller <djm@mindrot.org> |
@@ -49,9 +49,7 @@ int buffer_consume_end_ret(Buffer *, u_int); | |||
49 | 49 | ||
50 | #include <openssl/objects.h> | 50 | #include <openssl/objects.h> |
51 | #include <openssl/bn.h> | 51 | #include <openssl/bn.h> |
52 | void buffer_put_bignum(Buffer *, const BIGNUM *); | ||
53 | void buffer_put_bignum2(Buffer *, const BIGNUM *); | 52 | void buffer_put_bignum2(Buffer *, const BIGNUM *); |
54 | void buffer_get_bignum(Buffer *, BIGNUM *); | ||
55 | void buffer_get_bignum2(Buffer *, BIGNUM *); | 53 | void buffer_get_bignum2(Buffer *, BIGNUM *); |
56 | void buffer_put_bignum2_from_string(Buffer *, const u_char *, u_int); | 54 | void buffer_put_bignum2_from_string(Buffer *, const u_char *, u_int); |
57 | 55 | ||
@@ -75,8 +73,6 @@ void buffer_put_cstring(Buffer *, const char *); | |||
75 | 73 | ||
76 | #define buffer_skip_string(b) (void)buffer_get_string_ptr(b, NULL); | 74 | #define buffer_skip_string(b) (void)buffer_get_string_ptr(b, NULL); |
77 | 75 | ||
78 | int buffer_put_bignum_ret(Buffer *, const BIGNUM *); | ||
79 | int buffer_get_bignum_ret(Buffer *, BIGNUM *); | ||
80 | int buffer_put_bignum2_ret(Buffer *, const BIGNUM *); | 76 | int buffer_put_bignum2_ret(Buffer *, const BIGNUM *); |
81 | int buffer_get_bignum2_ret(Buffer *, BIGNUM *); | 77 | int buffer_get_bignum2_ret(Buffer *, BIGNUM *); |
82 | int buffer_get_short_ret(u_short *, Buffer *); | 78 | int buffer_get_short_ret(u_short *, Buffer *); |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: packet.c,v 1.249 2017/04/30 23:13:25 djm Exp $ */ | 1 | /* $OpenBSD: packet.c,v 1.250 2017/04/30 23:23:54 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -1397,153 +1397,6 @@ ssh_packet_read_expect(struct ssh *ssh, u_int expected_type) | |||
1397 | return 0; | 1397 | return 0; |
1398 | } | 1398 | } |
1399 | 1399 | ||
1400 | /* Checks if a full packet is available in the data received so far via | ||
1401 | * packet_process_incoming. If so, reads the packet; otherwise returns | ||
1402 | * SSH_MSG_NONE. This does not wait for data from the connection. | ||
1403 | * | ||
1404 | * SSH_MSG_DISCONNECT is handled specially here. Also, | ||
1405 | * SSH_MSG_IGNORE messages are skipped by this function and are never returned | ||
1406 | * to higher levels. | ||
1407 | */ | ||
1408 | |||
1409 | int | ||
1410 | ssh_packet_read_poll1(struct ssh *ssh, u_char *typep) | ||
1411 | { | ||
1412 | struct session_state *state = ssh->state; | ||
1413 | u_int len, padded_len; | ||
1414 | const char *emsg; | ||
1415 | const u_char *cp; | ||
1416 | u_char *p; | ||
1417 | u_int checksum, stored_checksum; | ||
1418 | int r; | ||
1419 | |||
1420 | *typep = SSH_MSG_NONE; | ||
1421 | |||
1422 | /* Check if input size is less than minimum packet size. */ | ||
1423 | if (sshbuf_len(state->input) < 4 + 8) | ||
1424 | return 0; | ||
1425 | /* Get length of incoming packet. */ | ||
1426 | len = PEEK_U32(sshbuf_ptr(state->input)); | ||
1427 | if (len < 1 + 2 + 2 || len > 256 * 1024) { | ||
1428 | if ((r = sshpkt_disconnect(ssh, "Bad packet length %u", | ||
1429 | len)) != 0) | ||
1430 | return r; | ||
1431 | return SSH_ERR_CONN_CORRUPT; | ||
1432 | } | ||
1433 | padded_len = (len + 8) & ~7; | ||
1434 | |||
1435 | /* Check if the packet has been entirely received. */ | ||
1436 | if (sshbuf_len(state->input) < 4 + padded_len) | ||
1437 | return 0; | ||
1438 | |||
1439 | /* The entire packet is in buffer. */ | ||
1440 | |||
1441 | /* Consume packet length. */ | ||
1442 | if ((r = sshbuf_consume(state->input, 4)) != 0) | ||
1443 | goto out; | ||
1444 | |||
1445 | /* | ||
1446 | * Cryptographic attack detector for ssh | ||
1447 | * (C)1998 CORE-SDI, Buenos Aires Argentina | ||
1448 | * Ariel Futoransky(futo@core-sdi.com) | ||
1449 | */ | ||
1450 | if (!cipher_ctx_is_plaintext(state->receive_context)) { | ||
1451 | emsg = NULL; | ||
1452 | switch (detect_attack(&state->deattack, | ||
1453 | sshbuf_ptr(state->input), padded_len)) { | ||
1454 | case DEATTACK_OK: | ||
1455 | break; | ||
1456 | case DEATTACK_DETECTED: | ||
1457 | emsg = "crc32 compensation attack detected"; | ||
1458 | break; | ||
1459 | case DEATTACK_DOS_DETECTED: | ||
1460 | emsg = "deattack denial of service detected"; | ||
1461 | break; | ||
1462 | default: | ||
1463 | emsg = "deattack error"; | ||
1464 | break; | ||
1465 | } | ||
1466 | if (emsg != NULL) { | ||
1467 | error("%s", emsg); | ||
1468 | if ((r = sshpkt_disconnect(ssh, "%s", emsg)) != 0 || | ||
1469 | (r = ssh_packet_write_wait(ssh)) != 0) | ||
1470 | return r; | ||
1471 | return SSH_ERR_CONN_CORRUPT; | ||
1472 | } | ||
1473 | } | ||
1474 | |||
1475 | /* Decrypt data to incoming_packet. */ | ||
1476 | sshbuf_reset(state->incoming_packet); | ||
1477 | if ((r = sshbuf_reserve(state->incoming_packet, padded_len, &p)) != 0) | ||
1478 | goto out; | ||
1479 | if ((r = cipher_crypt(state->receive_context, 0, p, | ||
1480 | sshbuf_ptr(state->input), padded_len, 0, 0)) != 0) | ||
1481 | goto out; | ||
1482 | |||
1483 | if ((r = sshbuf_consume(state->input, padded_len)) != 0) | ||
1484 | goto out; | ||
1485 | |||
1486 | #ifdef PACKET_DEBUG | ||
1487 | fprintf(stderr, "read_poll plain: "); | ||
1488 | sshbuf_dump(state->incoming_packet, stderr); | ||
1489 | #endif | ||
1490 | |||
1491 | /* Compute packet checksum. */ | ||
1492 | checksum = ssh_crc32(sshbuf_ptr(state->incoming_packet), | ||
1493 | sshbuf_len(state->incoming_packet) - 4); | ||
1494 | |||
1495 | /* Skip padding. */ | ||
1496 | if ((r = sshbuf_consume(state->incoming_packet, 8 - len % 8)) != 0) | ||
1497 | goto out; | ||
1498 | |||
1499 | /* Test check bytes. */ | ||
1500 | if (len != sshbuf_len(state->incoming_packet)) { | ||
1501 | error("%s: len %d != sshbuf_len %zd", __func__, | ||
1502 | len, sshbuf_len(state->incoming_packet)); | ||
1503 | if ((r = sshpkt_disconnect(ssh, "invalid packet length")) != 0 || | ||
1504 | (r = ssh_packet_write_wait(ssh)) != 0) | ||
1505 | return r; | ||
1506 | return SSH_ERR_CONN_CORRUPT; | ||
1507 | } | ||
1508 | |||
1509 | cp = sshbuf_ptr(state->incoming_packet) + len - 4; | ||
1510 | stored_checksum = PEEK_U32(cp); | ||
1511 | if (checksum != stored_checksum) { | ||
1512 | error("Corrupted check bytes on input"); | ||
1513 | if ((r = sshpkt_disconnect(ssh, "connection corrupted")) != 0 || | ||
1514 | (r = ssh_packet_write_wait(ssh)) != 0) | ||
1515 | return r; | ||
1516 | return SSH_ERR_CONN_CORRUPT; | ||
1517 | } | ||
1518 | if ((r = sshbuf_consume_end(state->incoming_packet, 4)) < 0) | ||
1519 | goto out; | ||
1520 | |||
1521 | if (state->packet_compression) { | ||
1522 | sshbuf_reset(state->compression_buffer); | ||
1523 | if ((r = uncompress_buffer(ssh, state->incoming_packet, | ||
1524 | state->compression_buffer)) != 0) | ||
1525 | goto out; | ||
1526 | sshbuf_reset(state->incoming_packet); | ||
1527 | if ((r = sshbuf_putb(state->incoming_packet, | ||
1528 | state->compression_buffer)) != 0) | ||
1529 | goto out; | ||
1530 | } | ||
1531 | state->p_read.packets++; | ||
1532 | state->p_read.bytes += padded_len + 4; | ||
1533 | if ((r = sshbuf_get_u8(state->incoming_packet, typep)) != 0) | ||
1534 | goto out; | ||
1535 | if (*typep < SSH_MSG_MIN || *typep > SSH_MSG_MAX) { | ||
1536 | error("Invalid ssh1 packet type: %d", *typep); | ||
1537 | if ((r = sshpkt_disconnect(ssh, "invalid packet type")) != 0 || | ||
1538 | (r = ssh_packet_write_wait(ssh)) != 0) | ||
1539 | return r; | ||
1540 | return SSH_ERR_PROTOCOL_ERROR; | ||
1541 | } | ||
1542 | r = 0; | ||
1543 | out: | ||
1544 | return r; | ||
1545 | } | ||
1546 | |||
1547 | static int | 1400 | static int |
1548 | ssh_packet_read_poll2_mux(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) | 1401 | ssh_packet_read_poll2_mux(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) |
1549 | { | 1402 | { |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: packet.h,v 1.77 2017/04/30 23:13:25 djm Exp $ */ | 1 | /* $OpenBSD: packet.h,v 1.78 2017/04/30 23:23:54 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
@@ -118,7 +118,6 @@ int ssh_packet_send2(struct ssh *); | |||
118 | int ssh_packet_read(struct ssh *); | 118 | int ssh_packet_read(struct ssh *); |
119 | int ssh_packet_read_expect(struct ssh *, u_int type); | 119 | int ssh_packet_read_expect(struct ssh *, u_int type); |
120 | int ssh_packet_read_poll(struct ssh *); | 120 | int ssh_packet_read_poll(struct ssh *); |
121 | int ssh_packet_read_poll1(struct ssh *, u_char *); | ||
122 | int ssh_packet_read_poll2(struct ssh *, u_char *, u_int32_t *seqnr_p); | 121 | int ssh_packet_read_poll2(struct ssh *, u_char *, u_int32_t *seqnr_p); |
123 | int ssh_packet_process_incoming(struct ssh *, const char *buf, u_int len); | 122 | int ssh_packet_process_incoming(struct ssh *, const char *buf, u_int len); |
124 | int ssh_packet_read_seqnr(struct ssh *, u_char *, u_int32_t *seqnr_p); | 123 | int ssh_packet_read_seqnr(struct ssh *, u_char *, u_int32_t *seqnr_p); |
@@ -181,7 +180,6 @@ int sshpkt_put_string(struct ssh *ssh, const void *v, size_t len); | |||
181 | int sshpkt_put_cstring(struct ssh *ssh, const void *v); | 180 | int sshpkt_put_cstring(struct ssh *ssh, const void *v); |
182 | int sshpkt_put_stringb(struct ssh *ssh, const struct sshbuf *v); | 181 | int sshpkt_put_stringb(struct ssh *ssh, const struct sshbuf *v); |
183 | int sshpkt_put_ec(struct ssh *ssh, const EC_POINT *v, const EC_GROUP *g); | 182 | int sshpkt_put_ec(struct ssh *ssh, const EC_POINT *v, const EC_GROUP *g); |
184 | int sshpkt_put_bignum1(struct ssh *ssh, const BIGNUM *v); | ||
185 | int sshpkt_put_bignum2(struct ssh *ssh, const BIGNUM *v); | 183 | int sshpkt_put_bignum2(struct ssh *ssh, const BIGNUM *v); |
186 | 184 | ||
187 | int sshpkt_get(struct ssh *ssh, void *valp, size_t len); | 185 | int sshpkt_get(struct ssh *ssh, void *valp, size_t len); |
@@ -192,7 +190,6 @@ int sshpkt_get_string(struct ssh *ssh, u_char **valp, size_t *lenp); | |||
192 | int sshpkt_get_string_direct(struct ssh *ssh, const u_char **valp, size_t *lenp); | 190 | int sshpkt_get_string_direct(struct ssh *ssh, const u_char **valp, size_t *lenp); |
193 | int sshpkt_get_cstring(struct ssh *ssh, char **valp, size_t *lenp); | 191 | int sshpkt_get_cstring(struct ssh *ssh, char **valp, size_t *lenp); |
194 | int sshpkt_get_ec(struct ssh *ssh, EC_POINT *v, const EC_GROUP *g); | 192 | int sshpkt_get_ec(struct ssh *ssh, EC_POINT *v, const EC_GROUP *g); |
195 | int sshpkt_get_bignum1(struct ssh *ssh, BIGNUM *v); | ||
196 | int sshpkt_get_bignum2(struct ssh *ssh, BIGNUM *v); | 193 | int sshpkt_get_bignum2(struct ssh *ssh, BIGNUM *v); |
197 | int sshpkt_get_end(struct ssh *ssh); | 194 | int sshpkt_get_end(struct ssh *ssh); |
198 | const u_char *sshpkt_ptr(struct ssh *, size_t *lenp); | 195 | const u_char *sshpkt_ptr(struct ssh *, size_t *lenp); |