- 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@
This commit is contained in:
Damien Miller 2013-10-30 22:19:47 +11:00
parent 28631ceaa7
commit 4a3a9d4bbf
3 changed files with 38 additions and 17 deletions

View File

@ -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 20131026
- (djm) OpenBSD CVS Sync - (djm) OpenBSD CVS Sync
- djm@cvs.openbsd.org 2013/10/25 23:04:51 - djm@cvs.openbsd.org 2013/10/25 23:04:51

45
key.c
View File

@ -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(): * read_bignum():
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -56,6 +56,7 @@
#include "ssh2.h" #include "ssh2.h"
static int to_blob(const Key *, u_char **, u_int *, int); 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 * static struct KeyCert *
cert_new(void) cert_new(void)
@ -1023,6 +1024,18 @@ key_alg_list(void)
return ret; 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 u_int
key_size(const Key *k) 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); buffer_clear(&tmp);
if ((key->cert->signature_key = key_from_blob(sig_key, if ((key->cert->signature_key = key_from_blob2(sig_key, sklen, 0))
sklen)) == NULL) { == NULL) {
error("%s: Signature key invalid", __func__); error("%s: Signature key invalid", __func__);
goto out; goto out;
} }
@ -1425,8 +1438,8 @@ cert_parse(Buffer *b, Key *key, const u_char *blob, u_int blen)
return ret; return ret;
} }
Key * static Key *
key_from_blob(const u_char *blob, u_int blen) key_from_blob2(const u_char *blob, u_int blen, int allow_cert)
{ {
Buffer b; Buffer b;
int rlen, type; int rlen, type;
@ -1452,7 +1465,10 @@ key_from_blob(const u_char *blob, u_int blen)
if (key_type_plain(type) == KEY_ECDSA) if (key_type_plain(type) == KEY_ECDSA)
nid = key_ecdsa_nid_from_name(ktype); nid = key_ecdsa_nid_from_name(ktype);
#endif #endif
if (!allow_cert && key_type_is_cert(type)) {
error("key_from_blob: certificate not allowed in this context");
goto out;
}
switch (type) { switch (type) {
case KEY_RSA_CERT: case KEY_RSA_CERT:
(void)buffer_get_string_ptr_ret(&b, NULL); /* Skip nonce */ (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; return key;
} }
Key *
key_from_blob(const u_char *blob, u_int blen)
{
return key_from_blob2(blob, blen, 1);
}
static int static int
to_blob(const Key *key, u_char **blobp, u_int *lenp, int force_plain) 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) if (k == NULL)
return 0; return 0;
switch (k->type) { return key_type_is_cert(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 the cert-less equivalent to a certified key type */ /* Return the cert-less equivalent to a certified key type */

3
key.h
View File

@ -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. * 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 *); Key *key_from_private(const Key *);
int key_type_from_name(char *); int key_type_from_name(char *);
int key_is_cert(const Key *); int key_is_cert(const Key *);
int key_type_is_cert(int);
int key_type_plain(int); int key_type_plain(int);
int key_to_certified(Key *, int); int key_to_certified(Key *, int);
int key_drop_cert(Key *); int key_drop_cert(Key *);