summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2015-05-21 04:55:51 +0000
committerDamien Miller <djm@mindrot.org>2015-05-21 15:06:06 +1000
commitd80fbe41a57c72420c87a628444da16d09d66ca7 (patch)
treee2bb0b30b20135044ac822ee2535c12337124fb6
parent7cc44ef74133a473734bbcbd3484f24d6a7328c5 (diff)
upstream commit
refactor: split base64 encoding of pubkey into its own sshkey_to_base64() function and out of sshkey_write(); ok markus@ Upstream-ID: 54fc38f5832e9b91028900819bda46c3959a0c1a
-rw-r--r--sshkey.c174
-rw-r--r--sshkey.h3
2 files changed, 101 insertions, 76 deletions
diff --git a/sshkey.c b/sshkey.c
index 83985ca5..cfe59808 100644
--- a/sshkey.c
+++ b/sshkey.c
@@ -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.
@@ -761,6 +761,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);
@@ -1409,98 +1415,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 *
diff --git a/sshkey.h b/sshkey.h
index 62c1c3e2..cdac0e25 100644
--- a/sshkey.h
+++ b/sshkey.h
@@ -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.
@@ -163,6 +163,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 *);