]> git.ipfire.org Git - thirdparty/openssh-portable.git/commitdiff
- djm@cvs.openbsd.org 2013/10/29 09:42:11
authorDamien Miller <djm@mindrot.org>
Wed, 30 Oct 2013 11:19:47 +0000 (22:19 +1100)
committerDamien Miller <djm@mindrot.org>
Wed, 30 Oct 2013 11:19:47 +0000 (22:19 +1100)
     [key.c key.h]
     fix potential stack exhaustion caused by nested certificates;
     report by Mateusz Kocielski; ok dtucker@ markus@

ChangeLog
key.c
key.h

index 4519a922e1203a544a96b818f26b2349d2856514..54f7b004260bec7777b1b51aff0ff3236a3a538a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
diff --git a/key.c b/key.c
index 55ee78998b7421229997490c79d9e2e626360b99..90f0a0173f2f0768dfa61a6650f82a9591a6ca77 100644 (file)
--- a/key.c
+++ b/key.c
@@ -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 */
diff --git a/key.h b/key.h
index 17358ae1f0829a268439d9c18de504fd6b010e8e..8a78a828ac978b40d37afa9c1f1937fa037ea9ec 100644 (file)
--- a/key.h
+++ b/key.h
@@ -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 *);