summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2013-10-30 22:19:47 +1100
committerDamien Miller <djm@mindrot.org>2013-10-30 22:19:47 +1100
commit4a3a9d4bbf8048473f5cc202cd8db7164d5e6b8d (patch)
tree87c013981b56858480c8ec0a354f9948c955d3a6
parent28631ceaa7acd9bc500f924614431542893c6a21 (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@
-rw-r--r--ChangeLog7
-rw-r--r--key.c45
-rw-r--r--key.h3
3 files changed, 38 insertions, 17 deletions
diff --git a/ChangeLog b/ChangeLog
index 4519a922e..54f7b0042 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
120131030
2 - (djm) OpenBSD CVS Sync
3 - djm@cvs.openbsd.org 2013/10/29 09:42:11
4 [key.c key.h]
5 fix potential stack exhaustion caused by nested certificates;
6 report by Mateusz Kocielski; ok dtucker@ markus@
7
120131026 820131026
2 - (djm) OpenBSD CVS Sync 9 - (djm) OpenBSD CVS Sync
3 - djm@cvs.openbsd.org 2013/10/25 23:04:51 10 - djm@cvs.openbsd.org 2013/10/25 23:04:51
diff --git a/key.c b/key.c
index 55ee78998..90f0a0173 100644
--- a/key.c
+++ b/key.c
@@ -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
58static int to_blob(const Key *, u_char **, u_int *, int); 58static int to_blob(const Key *, u_char **, u_int *, int);
59static Key *key_from_blob2(const u_char *, u_int, int);
59 60
60static struct KeyCert * 61static struct KeyCert *
61cert_new(void) 62cert_new(void)
@@ -1023,6 +1024,18 @@ key_alg_list(void)
1023 return ret; 1024 return ret;
1024} 1025}
1025 1026
1027int
1028key_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
1026u_int 1039u_int
1027key_size(const Key *k) 1040key_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
1428Key * 1441static Key *
1429key_from_blob(const u_char *blob, u_int blen) 1442key_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
1570Key *
1571key_from_blob(const u_char *blob, u_int blen)
1572{
1573 return key_from_blob2(blob, blen, 1);
1574}
1575
1554static int 1576static int
1555to_blob(const Key *key, u_char **blobp, u_int *lenp, int force_plain) 1577to_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 */
diff --git a/key.h b/key.h
index 17358ae1f..8a78a828a 100644
--- a/key.h
+++ b/key.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: key.h,v 1.37 2013/05/19 02:42:42 djm Exp $ */ 1/* $OpenBSD: key.h,v 1.38 2013/10/29 09:42:11 djm Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. 4 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
@@ -107,6 +107,7 @@ Key *key_generate(int, u_int);
107Key *key_from_private(const Key *); 107Key *key_from_private(const Key *);
108int key_type_from_name(char *); 108int key_type_from_name(char *);
109int key_is_cert(const Key *); 109int key_is_cert(const Key *);
110int key_type_is_cert(int);
110int key_type_plain(int); 111int key_type_plain(int);
111int key_to_certified(Key *, int); 112int key_to_certified(Key *, int);
112int key_drop_cert(Key *); 113int key_drop_cert(Key *);