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 | |
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@
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | key.c | 45 | ||||
-rw-r--r-- | key.h | 3 |
3 files changed, 38 insertions, 17 deletions
@@ -1,3 +1,10 @@ +20131030 + - (djm) OpenBSD CVS Sync + - 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@ + 20131026 - (djm) OpenBSD CVS Sync - djm@cvs.openbsd.org 2013/10/25 23:04:51 @@ -1,4 +1,4 @@ -/* $OpenBSD: key.c,v 1.104 2013/05/19 02:42:42 djm Exp $ */ +/* $OpenBSD: key.c,v 1.105 2013/10/29 09:42:11 djm Exp $ */ /* * read_bignum(): * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -56,6 +56,7 @@ #include "ssh2.h" static int to_blob(const Key *, u_char **, u_int *, int); +static Key *key_from_blob2(const u_char *, u_int, int); static struct KeyCert * cert_new(void) @@ -1023,6 +1024,18 @@ key_alg_list(void) return ret; } +int +key_type_is_cert(int type) +{ + const struct keytype *kt; + + for (kt = keytypes; kt->type != -1; kt++) { + if (kt->type == type) + return kt->cert; + } + return 0; +} + u_int key_size(const Key *k) { @@ -1387,8 +1400,8 @@ cert_parse(Buffer *b, Key *key, const u_char *blob, u_int blen) } buffer_clear(&tmp); - if ((key->cert->signature_key = key_from_blob(sig_key, - sklen)) == NULL) { + if ((key->cert->signature_key = key_from_blob2(sig_key, sklen, 0)) + == NULL) { error("%s: Signature key invalid", __func__); goto out; } @@ -1425,8 +1438,8 @@ cert_parse(Buffer *b, Key *key, const u_char *blob, u_int blen) return ret; } -Key * -key_from_blob(const u_char *blob, u_int blen) +static Key * +key_from_blob2(const u_char *blob, u_int blen, int allow_cert) { Buffer b; int rlen, type; @@ -1452,7 +1465,10 @@ key_from_blob(const u_char *blob, u_int blen) if (key_type_plain(type) == KEY_ECDSA) nid = key_ecdsa_nid_from_name(ktype); #endif - + if (!allow_cert && key_type_is_cert(type)) { + error("key_from_blob: certificate not allowed in this context"); + goto out; + } switch (type) { case KEY_RSA_CERT: (void)buffer_get_string_ptr_ret(&b, NULL); /* Skip nonce */ @@ -1551,6 +1567,12 @@ key_from_blob(const u_char *blob, u_int blen) return key; } +Key * +key_from_blob(const u_char *blob, u_int blen) +{ + return key_from_blob2(blob, blen, 1); +} + static int to_blob(const Key *key, u_char **blobp, u_int *lenp, int force_plain) { @@ -1747,16 +1769,7 @@ key_is_cert(const Key *k) { if (k == NULL) return 0; - switch (k->type) { - case KEY_RSA_CERT_V00: - case KEY_DSA_CERT_V00: - case KEY_RSA_CERT: - case KEY_DSA_CERT: - case KEY_ECDSA_CERT: - return 1; - default: - return 0; - } + return key_type_is_cert(k->type); } /* Return the cert-less equivalent to a certified key type */ @@ -1,4 +1,4 @@ -/* $OpenBSD: key.h,v 1.37 2013/05/19 02:42:42 djm Exp $ */ +/* $OpenBSD: key.h,v 1.38 2013/10/29 09:42:11 djm Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. @@ -107,6 +107,7 @@ Key *key_generate(int, u_int); Key *key_from_private(const Key *); int key_type_from_name(char *); int key_is_cert(const Key *); +int key_type_is_cert(int); int key_type_plain(int); int key_to_certified(Key *, int); int key_drop_cert(Key *); |