]> andersk Git - openssh.git/blobdiff - key.c
Whoops, forgot changelog
[openssh.git] / key.c
diff --git a/key.c b/key.c
index 437a5e2457f6b3e175d395a261a3c459b3c7248d..f7df0bb1db45b4f839bf91578ca2c8e6364725d0 100644 (file)
--- a/key.c
+++ b/key.c
@@ -1,4 +1,14 @@
 /*
+ * read_bignum():
+ * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
+ *
+ * As far as I am concerned, the code I have written for this software
+ * can be used freely for any purpose.  Any derived versions of this
+ * software must be clearly marked as such, and if the derived work is
+ * incompatible with the protocol description in the RFC file, it must be
+ * called by a name other than "ssh" or "Secure Shell".
+ *
+ *
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -9,11 +19,6 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Markus Friedl.
- * 4. The name of the author may not be used to endorse or promote products
- *    derived from this software without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-/*
- * read_bignum():
- * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
- */
 
 #include "includes.h"
-
-#ifdef HAVE_OPENSSL
-#include <openssl/bn.h>
+#include "ssh.h"
 #include <openssl/rsa.h>
 #include <openssl/dsa.h>
 #include <openssl/evp.h>
-#endif
-#ifdef HAVE_SSL
-#include <ssl/bn.h>
-#include <ssl/rsa.h>
-#include <ssl/dsa.h>
-#include <ssl/evp.h>
-#endif
-
-#include "ssh.h"
 #include "xmalloc.h"
 #include "key.h"
+#include "dsa.h"
+#include "uuencode.h"
+
+RCSID("$OpenBSD: key.c,v 1.11 2000/09/07 20:27:51 deraadt Exp $");
+
+#define SSH_DSS "ssh-dss"
 
 Key *
 key_new(int type)
@@ -58,6 +54,8 @@ key_new(int type)
        DSA *dsa;
        k = xmalloc(sizeof(*k));
        k->type = type;
+       k->dsa = NULL;
+       k->rsa = NULL;
        switch (k->type) {
        case KEY_RSA:
                rsa = RSA_new();
@@ -74,8 +72,6 @@ key_new(int type)
                k->dsa = dsa;
                break;
        case KEY_EMPTY:
-               k->dsa = NULL;
-               k->rsa = NULL;
                break;
        default:
                fatal("key_new: bad key type %d", k->type);
@@ -122,14 +118,12 @@ key_equal(Key *a, Key *b)
                    BN_cmp(a->dsa->pub_key, b->dsa->pub_key) == 0;
                break;
        default:
-               fatal("key_free: bad key type %d", a->type);
+               fatal("key_equal: bad key type %d", a->type);
                break;
        }
        return 0;
 }
 
-#define FPRINT "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x"
-
 /*
  * Generate key fingerprint in ascii format.
  * Based on ideas and code from Bjoern Groenvall <bg@sics.se>
@@ -137,47 +131,45 @@ key_equal(Key *a, Key *b)
 char *
 key_fingerprint(Key *k)
 {
-       static char retval[80];
-       unsigned char *buf = NULL;
+       static char retval[(EVP_MAX_MD_SIZE+1)*3];
+       unsigned char *blob = NULL;
        int len = 0;
-       int nlen, elen, plen, qlen, glen, publen;
+       int nlen, elen;
 
        switch (k->type) {
        case KEY_RSA:
                nlen = BN_num_bytes(k->rsa->n);
                elen = BN_num_bytes(k->rsa->e);
                len = nlen + elen;
-               buf = xmalloc(len);
-               BN_bn2bin(k->rsa->n, buf);
-               BN_bn2bin(k->rsa->e, buf + nlen);
+               blob = xmalloc(len);
+               BN_bn2bin(k->rsa->n, blob);
+               BN_bn2bin(k->rsa->e, blob + nlen);
                break;
        case KEY_DSA:
-               plen = BN_num_bytes(k->dsa->p);
-               qlen = BN_num_bytes(k->dsa->q);
-               glen = BN_num_bytes(k->dsa->g);
-               publen = BN_num_bytes(k->dsa->pub_key);
-               len = qlen + qlen + glen + publen;
-               buf = xmalloc(len);
-               BN_bn2bin(k->dsa->p, buf);
-               BN_bn2bin(k->dsa->q, buf + plen);
-               BN_bn2bin(k->dsa->g, buf + plen + qlen);
-               BN_bn2bin(k->dsa->pub_key , buf + plen + qlen + glen);
+               dsa_make_key_blob(k, &blob, &len);
                break;
        default:
                fatal("key_fingerprint: bad key type %d", k->type);
                break;
        }
-       if (buf != NULL) {
-               unsigned char d[16];
-               EVP_MD_CTX md;
-               EVP_DigestInit(&md, EVP_md5());
-               EVP_DigestUpdate(&md, buf, len);
-               EVP_DigestFinal(&md, d, NULL);
-               snprintf(retval, sizeof(retval), FPRINT,
-                   d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7],
-                   d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]);
-               memset(buf, 0, len);
-               xfree(buf);
+       retval[0] = '\0';
+
+       if (blob != NULL) {
+               int i;
+               unsigned char digest[EVP_MAX_MD_SIZE];
+               EVP_MD *md = EVP_md5();
+               EVP_MD_CTX ctx;
+               EVP_DigestInit(&ctx, md);
+               EVP_DigestUpdate(&ctx, blob, len);
+               EVP_DigestFinal(&ctx, digest, NULL);
+               for(i = 0; i < md->md_size; i++) {
+                       char hex[4];
+                       snprintf(hex, sizeof(hex), "%02x:", digest[i]);
+                       strlcat(retval, hex, sizeof(retval));
+               }
+               retval[strlen(retval) - 1] = '\0';
+               memset(blob, 0, len);
+               xfree(blob);
        }
        return retval;
 }
@@ -237,13 +229,27 @@ write_bignum(FILE *f, BIGNUM *num)
        free(buf);
        return 1;
 }
-int
-key_read(Key *ret, unsigned int bits, char **cpp)
+unsigned int
+key_read(Key *ret, char **cpp)
 {
+       Key *k;
+       unsigned int bits = 0;
+       char *cp;
+       int len, n;
+       unsigned char *blob;
+
+       cp = *cpp;
+
        switch(ret->type) {
        case KEY_RSA:
+               /* Get number of bits. */
+               if (*cp < '0' || *cp > '9')
+                       return 0;       /* Bad bit count... */
+               for (bits = 0; *cp >= '0' && *cp <= '9'; cp++)
+                       bits = 10 * bits + *cp - '0';
                if (bits == 0)
                        return 0;
+               *cpp = cp;
                /* Get public exponent, public modulus. */
                if (!read_bignum(cpp, ret->rsa->e))
                        return 0;
@@ -251,22 +257,40 @@ key_read(Key *ret, unsigned int bits, char **cpp)
                        return 0;
                break;
        case KEY_DSA:
-               if (bits != 0)
+               if (strncmp(cp, SSH_DSS " ", 7) != 0)
                        return 0;
-               if (!read_bignum(cpp, ret->dsa->p))
+               cp += 7;
+               len = 2*strlen(cp);
+               blob = xmalloc(len);
+               n = uudecode(cp, blob, len);
+               if (n < 0) {
+                       error("key_read: uudecode %s failed", cp);
                        return 0;
-               if (!read_bignum(cpp, ret->dsa->q))
-                       return 0;
-               if (!read_bignum(cpp, ret->dsa->g))
-                       return 0;
-               if (!read_bignum(cpp, ret->dsa->pub_key))
+               }
+               k = dsa_key_from_blob(blob, n);
+               if (k == NULL) {
+                       error("key_read: dsa_key_from_blob %s failed", cp);
                        return 0;
+               }
+               xfree(blob);
+               if (ret->dsa != NULL)
+                       DSA_free(ret->dsa);
+               ret->dsa = k->dsa;
+               k->dsa = NULL;
+               key_free(k);
+               bits = BN_num_bits(ret->dsa->p);
+               /* advance cp: skip whitespace and data */
+               while (*cp == ' ' || *cp == '\t')
+                       cp++;
+               while (*cp != '\0' && *cp != ' ' && *cp != '\t')
+                       cp++;
+               *cpp = cp;
                break;
        default:
-               fatal("bad key type: %d", ret->type);
+               fatal("key_read: bad key type: %d", ret->type);
                break;
        }
-       return 1;
+       return bits;
 }
 int
 key_write(Key *key, FILE *f)
@@ -285,17 +309,42 @@ key_write(Key *key, FILE *f)
                        error("key_write: failed for RSA key");
                }
        } else if (key->type == KEY_DSA && key->dsa != NULL) {
-               /* bits == 0 means DSA key */
-               bits = 0;
-               fprintf(f, "%u", bits);
-               if (write_bignum(f, key->dsa->p) &&
-                   write_bignum(f, key->dsa->q) &&
-                   write_bignum(f, key->dsa->g) &&
-                   write_bignum(f, key->dsa->pub_key)) {
+               int len, n;
+               unsigned char *blob, *uu;
+               dsa_make_key_blob(key, &blob, &len);
+               uu = xmalloc(2*len);
+               n = uuencode(blob, len, uu, 2*len);
+               if (n > 0) {
+                       fprintf(f, "%s %s", SSH_DSS, uu);
                        success = 1;
-               } else {
-                       error("key_write: failed for DSA key");
                }
+               xfree(blob);
+               xfree(uu);
        }
        return success;
 }
+char *
+key_type(Key *k)
+{
+       switch (k->type) {
+       case KEY_RSA:
+               return "RSA";
+               break;
+       case KEY_DSA:
+               return "DSA";
+               break;
+       }
+       return "unknown";
+}
+unsigned int
+key_size(Key *k){
+       switch (k->type) {
+       case KEY_RSA:
+               return BN_num_bits(k->rsa->n);
+               break;
+       case KEY_DSA:
+               return BN_num_bits(k->dsa->p);
+               break;
+       }
+       return 0;
+}
This page took 0.065752 seconds and 4 git commands to generate.