diff options
author | Damien Miller <djm@mindrot.org> | 2013-10-30 22:19:47 +1100 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2013-10-30 22:19:47 +1100 |
commit | 4a3a9d4bbf8048473f5cc202cd8db7164d5e6b8d (patch) | |
tree | 87c013981b56858480c8ec0a354f9948c955d3a6 /key.c | |
parent | 28631ceaa7acd9bc500f924614431542893c6a21 (diff) |
- djm@cvs.openbsd.org 2013/10/29 09:42:11
[key.c key.h]
fix potential stack exhaustion caused by nested certificates;
report by Mateusz Kocielski; ok dtucker@ markus@
Diffstat (limited to 'key.c')
-rw-r--r-- | key.c | 45 |
1 files changed, 29 insertions, 16 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: key.c,v 1.104 2013/05/19 02:42:42 djm Exp $ */ | 1 | /* $OpenBSD: key.c,v 1.105 2013/10/29 09:42:11 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * read_bignum(): | 3 | * read_bignum(): |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -56,6 +56,7 @@ | |||
56 | #include "ssh2.h" | 56 | #include "ssh2.h" |
57 | 57 | ||
58 | static int to_blob(const Key *, u_char **, u_int *, int); | 58 | static int to_blob(const Key *, u_char **, u_int *, int); |
59 | static Key *key_from_blob2(const u_char *, u_int, int); | ||
59 | 60 | ||
60 | static struct KeyCert * | 61 | static struct KeyCert * |
61 | cert_new(void) | 62 | cert_new(void) |
@@ -1023,6 +1024,18 @@ key_alg_list(void) | |||
1023 | return ret; | 1024 | return ret; |
1024 | } | 1025 | } |
1025 | 1026 | ||
1027 | int | ||
1028 | key_type_is_cert(int type) | ||
1029 | { | ||
1030 | const struct keytype *kt; | ||
1031 | |||
1032 | for (kt = keytypes; kt->type != -1; kt++) { | ||
1033 | if (kt->type == type) | ||
1034 | return kt->cert; | ||
1035 | } | ||
1036 | return 0; | ||
1037 | } | ||
1038 | |||
1026 | u_int | 1039 | u_int |
1027 | key_size(const Key *k) | 1040 | key_size(const Key *k) |
1028 | { | 1041 | { |
@@ -1387,8 +1400,8 @@ cert_parse(Buffer *b, Key *key, const u_char *blob, u_int blen) | |||
1387 | } | 1400 | } |
1388 | buffer_clear(&tmp); | 1401 | buffer_clear(&tmp); |
1389 | 1402 | ||
1390 | if ((key->cert->signature_key = key_from_blob(sig_key, | 1403 | if ((key->cert->signature_key = key_from_blob2(sig_key, sklen, 0)) |
1391 | sklen)) == NULL) { | 1404 | == NULL) { |
1392 | error("%s: Signature key invalid", __func__); | 1405 | error("%s: Signature key invalid", __func__); |
1393 | goto out; | 1406 | goto out; |
1394 | } | 1407 | } |
@@ -1425,8 +1438,8 @@ cert_parse(Buffer *b, Key *key, const u_char *blob, u_int blen) | |||
1425 | return ret; | 1438 | return ret; |
1426 | } | 1439 | } |
1427 | 1440 | ||
1428 | Key * | 1441 | static Key * |
1429 | key_from_blob(const u_char *blob, u_int blen) | 1442 | key_from_blob2(const u_char *blob, u_int blen, int allow_cert) |
1430 | { | 1443 | { |
1431 | Buffer b; | 1444 | Buffer b; |
1432 | int rlen, type; | 1445 | int rlen, type; |
@@ -1452,7 +1465,10 @@ key_from_blob(const u_char *blob, u_int blen) | |||
1452 | if (key_type_plain(type) == KEY_ECDSA) | 1465 | if (key_type_plain(type) == KEY_ECDSA) |
1453 | nid = key_ecdsa_nid_from_name(ktype); | 1466 | nid = key_ecdsa_nid_from_name(ktype); |
1454 | #endif | 1467 | #endif |
1455 | 1468 | if (!allow_cert && key_type_is_cert(type)) { | |
1469 | error("key_from_blob: certificate not allowed in this context"); | ||
1470 | goto out; | ||
1471 | } | ||
1456 | switch (type) { | 1472 | switch (type) { |
1457 | case KEY_RSA_CERT: | 1473 | case KEY_RSA_CERT: |
1458 | (void)buffer_get_string_ptr_ret(&b, NULL); /* Skip nonce */ | 1474 | (void)buffer_get_string_ptr_ret(&b, NULL); /* Skip nonce */ |
@@ -1551,6 +1567,12 @@ key_from_blob(const u_char *blob, u_int blen) | |||
1551 | return key; | 1567 | return key; |
1552 | } | 1568 | } |
1553 | 1569 | ||
1570 | Key * | ||
1571 | key_from_blob(const u_char *blob, u_int blen) | ||
1572 | { | ||
1573 | return key_from_blob2(blob, blen, 1); | ||
1574 | } | ||
1575 | |||
1554 | static int | 1576 | static int |
1555 | to_blob(const Key *key, u_char **blobp, u_int *lenp, int force_plain) | 1577 | to_blob(const Key *key, u_char **blobp, u_int *lenp, int force_plain) |
1556 | { | 1578 | { |
@@ -1747,16 +1769,7 @@ key_is_cert(const Key *k) | |||
1747 | { | 1769 | { |
1748 | if (k == NULL) | 1770 | if (k == NULL) |
1749 | return 0; | 1771 | return 0; |
1750 | switch (k->type) { | 1772 | return key_type_is_cert(k->type); |
1751 | case KEY_RSA_CERT_V00: | ||
1752 | case KEY_DSA_CERT_V00: | ||
1753 | case KEY_RSA_CERT: | ||
1754 | case KEY_DSA_CERT: | ||
1755 | case KEY_ECDSA_CERT: | ||
1756 | return 1; | ||
1757 | default: | ||
1758 | return 0; | ||
1759 | } | ||
1760 | } | 1773 | } |
1761 | 1774 | ||
1762 | /* Return the cert-less equivalent to a certified key type */ | 1775 | /* Return the cert-less equivalent to a certified key type */ |