refactor: split base64 encoding of pubkey into its own
authordjm <djm@openbsd.org>
Thu, 21 May 2015 04:55:51 +0000 (04:55 +0000)
committerdjm <djm@openbsd.org>
Thu, 21 May 2015 04:55:51 +0000 (04:55 +0000)
sshkey_to_base64() function and out of sshkey_write();
ok markus@

usr.bin/ssh/sshkey.c
usr.bin/ssh/sshkey.h

index e9a23e7..50782cb 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshkey.c,v 1.18 2015/05/08 03:17:49 djm Exp $ */
+/* $OpenBSD: sshkey.c,v 1.19 2015/05/21 04:55:51 djm Exp $ */
 /*
  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
  * Copyright (c) 2008 Alexander von Gernler.  All rights reserved.
@@ -737,6 +737,12 @@ to_blob_buf(const struct sshkey *key, struct sshbuf *b, int force_plain)
        if (key == NULL)
                return SSH_ERR_INVALID_ARGUMENT;
 
+       if (sshkey_is_cert(key)) {
+               if (key->cert == NULL)
+                       return SSH_ERR_EXPECTED_CERT;
+               if (sshbuf_len(key->cert->certblob) == 0)
+                       return SSH_ERR_KEY_LACKS_CERTBLOB;
+       }
        type = force_plain ? sshkey_type_plain(key->type) : key->type;
        typename = sshkey_ssh_name_from_type_nid(type, key->ecdsa_nid);
 
@@ -1381,98 +1387,116 @@ sshkey_read(struct sshkey *ret, char **cpp)
 }
 
 int
-sshkey_write(const struct sshkey *key, FILE *f)
+sshkey_to_base64(const struct sshkey *key, char **b64p)
 {
-       int ret = SSH_ERR_INTERNAL_ERROR;
-       struct sshbuf *b = NULL, *bb = NULL;
+       int r = SSH_ERR_INTERNAL_ERROR;
+       struct sshbuf *b = NULL;
        char *uu = NULL;
+
+       if (b64p != NULL)
+               *b64p = NULL;
+       if ((b = sshbuf_new()) == NULL)
+               return SSH_ERR_ALLOC_FAIL;
+       if ((r = sshkey_putb(key, b)) != 0)
+               goto out;
+       if ((uu = sshbuf_dtob64(b)) == NULL) {
+               r = SSH_ERR_ALLOC_FAIL;
+               goto out;
+       }
+       /* Success */
+       if (b64p != NULL) {
+               *b64p = uu;
+               uu = NULL;
+       }
+       r = 0;
+ out:
+       sshbuf_free(b);
+       free(uu);
+       return r;
+}
+
+static int
+sshkey_format_rsa1(const struct sshkey *key, struct sshbuf *b)
+{
+       int r = SSH_ERR_INTERNAL_ERROR;
 #ifdef WITH_SSH1
        u_int bits = 0;
        char *dec_e = NULL, *dec_n = NULL;
-#endif /* WITH_SSH1 */
 
-       if (sshkey_is_cert(key)) {
-               if (key->cert == NULL)
-                       return SSH_ERR_EXPECTED_CERT;
-               if (sshbuf_len(key->cert->certblob) == 0)
-                       return SSH_ERR_KEY_LACKS_CERTBLOB;
+       if (key->rsa == NULL || key->rsa->e == NULL ||
+           key->rsa->n == NULL) {
+               r = SSH_ERR_INVALID_ARGUMENT;
+               goto out;
        }
-       if ((b = sshbuf_new()) == NULL)
-               return SSH_ERR_ALLOC_FAIL;
-       switch (key->type) {
-#ifdef WITH_SSH1
-       case KEY_RSA1:
-               if (key->rsa == NULL || key->rsa->e == NULL ||
-                   key->rsa->n == NULL) {
-                       ret = SSH_ERR_INVALID_ARGUMENT;
-                       goto out;
-               }
-               if ((dec_e = BN_bn2dec(key->rsa->e)) == NULL ||
-                   (dec_n = BN_bn2dec(key->rsa->n)) == NULL) {
-                       ret = SSH_ERR_ALLOC_FAIL;
-                       goto out;
-               }
-               /* size of modulus 'n' */
-               if ((bits = BN_num_bits(key->rsa->n)) <= 0) {
-                       ret = SSH_ERR_INVALID_ARGUMENT;
-                       goto out;
-               }
-               if ((ret = sshbuf_putf(b, "%u %s %s", bits, dec_e, dec_n)) != 0)
-                       goto out;
+       if ((dec_e = BN_bn2dec(key->rsa->e)) == NULL ||
+           (dec_n = BN_bn2dec(key->rsa->n)) == NULL) {
+               r = SSH_ERR_ALLOC_FAIL;
+               goto out;
+       }
+       /* size of modulus 'n' */
+       if ((bits = BN_num_bits(key->rsa->n)) <= 0) {
+               r = SSH_ERR_INVALID_ARGUMENT;
+               goto out;
+       }
+       if ((r = sshbuf_putf(b, "%u %s %s", bits, dec_e, dec_n)) != 0)
+               goto out;
+
+       /* Success */
+       r = 0;
+ out:
+       if (dec_e != NULL)
+               OPENSSL_free(dec_e);
+       if (dec_n != NULL)
+               OPENSSL_free(dec_n);
 #endif /* WITH_SSH1 */
-               break;
-#ifdef WITH_OPENSSL
-       case KEY_DSA:
-       case KEY_DSA_CERT_V00:
-       case KEY_DSA_CERT:
-       case KEY_ECDSA:
-       case KEY_ECDSA_CERT:
-       case KEY_RSA:
-       case KEY_RSA_CERT_V00:
-       case KEY_RSA_CERT:
-#endif /* WITH_OPENSSL */
-       case KEY_ED25519:
-       case KEY_ED25519_CERT:
-               if ((bb = sshbuf_new()) == NULL) {
-                       ret = SSH_ERR_ALLOC_FAIL;
-                       goto out;
-               }
-               if ((ret = sshkey_putb(key, bb)) != 0)
-                       goto out;
-               if ((uu = sshbuf_dtob64(bb)) == NULL) {
-                       ret = SSH_ERR_ALLOC_FAIL;
+
+       return r;
+}
+
+static int
+sshkey_format_text(const struct sshkey *key, struct sshbuf *b)
+{
+       int r = SSH_ERR_INTERNAL_ERROR;
+       char *uu = NULL;
+
+       if (key->type == KEY_RSA1) {
+               if ((r = sshkey_format_rsa1(key, b)) != 0)
                        goto out;
-               }
-               if ((ret = sshbuf_putf(b, "%s ", sshkey_ssh_name(key))) != 0)
+       } else {
+               /* Unsupported key types handled in sshkey_to_base64() */
+               if ((r = sshkey_to_base64(key, &uu)) != 0)
                        goto out;
-               if ((ret = sshbuf_put(b, uu, strlen(uu))) != 0)
+               if ((r = sshbuf_putf(b, "%s %s",
+                   sshkey_ssh_name(key), uu)) != 0)
                        goto out;
-               break;
-       default:
-               ret = SSH_ERR_KEY_TYPE_UNKNOWN;
-               goto out;
        }
+       r = 0;
+ out:
+       free(uu);
+       return r;
+}
+
+int
+sshkey_write(const struct sshkey *key, FILE *f)
+{
+       struct sshbuf *b = NULL;
+       int r = SSH_ERR_INTERNAL_ERROR;
+
+       if ((b = sshbuf_new()) == NULL)
+               return SSH_ERR_ALLOC_FAIL;
+       if ((r = sshkey_format_text(key, b)) != 0)
+               goto out;
        if (fwrite(sshbuf_ptr(b), sshbuf_len(b), 1, f) != 1) {
                if (feof(f))
                        errno = EPIPE;
-               ret = SSH_ERR_SYSTEM_ERROR;
+               r = SSH_ERR_SYSTEM_ERROR;
                goto out;
        }
-       ret = 0;
+       /* Success */
+       r = 0;
  out:
-       if (b != NULL)
-               sshbuf_free(b);
-       if (bb != NULL)
-               sshbuf_free(bb);
-       if (uu != NULL)
-               free(uu);
-#ifdef WITH_SSH1
-       if (dec_e != NULL)
-               OPENSSL_free(dec_e);
-       if (dec_n != NULL)
-               OPENSSL_free(dec_n);
-#endif /* WITH_SSH1 */
-       return ret;
+       sshbuf_free(b);
+       return r;
 }
 
 const char *
index e05b407..e656b4a 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshkey.h,v 1.5 2015/01/26 02:59:11 djm Exp $ */
+/* $OpenBSD: sshkey.h,v 1.6 2015/05/21 04:55:51 djm Exp $ */
 
 /*
  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
@@ -157,6 +157,7 @@ int  sshkey_from_blob(const u_char *, size_t, struct sshkey **);
 int     sshkey_fromb(struct sshbuf *, struct sshkey **);
 int     sshkey_froms(struct sshbuf *, struct sshkey **);
 int     sshkey_to_blob(const struct sshkey *, u_char **, size_t *);
+int     sshkey_to_base64(const struct sshkey *, char **);
 int     sshkey_putb(const struct sshkey *, struct sshbuf *);
 int     sshkey_puts(const struct sshkey *, struct sshbuf *);
 int     sshkey_plain_to_blob(const struct sshkey *, u_char **, size_t *);