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
This commit is contained in:
djm@openbsd.org 2015-05-21 04:55:51 +00:00 committed by Damien Miller
parent 7cc44ef741
commit d80fbe41a5
2 changed files with 103 additions and 78 deletions

178
sshkey.c
View 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.
@ -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 ((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;
#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;
goto out;
}
if ((ret = sshbuf_putf(b, "%s ", sshkey_ssh_name(key))) != 0)
goto out;
if ((ret = sshbuf_put(b, uu, strlen(uu))) != 0)
goto out;
break;
default:
ret = SSH_ERR_KEY_TYPE_UNKNOWN;
if (key->rsa == NULL || key->rsa->e == NULL ||
key->rsa->n == NULL) {
r = SSH_ERR_INVALID_ARGUMENT;
goto out;
}
if (fwrite(sshbuf_ptr(b), sshbuf_len(b), 1, f) != 1) {
if (feof(f))
errno = EPIPE;
ret = SSH_ERR_SYSTEM_ERROR;
if ((dec_e = BN_bn2dec(key->rsa->e)) == NULL ||
(dec_n = BN_bn2dec(key->rsa->n)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
ret = 0;
/* 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 (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;
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;
} else {
/* Unsupported key types handled in sshkey_to_base64() */
if ((r = sshkey_to_base64(key, &uu)) != 0)
goto out;
if ((r = sshbuf_putf(b, "%s %s",
sshkey_ssh_name(key), uu)) != 0)
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;
r = SSH_ERR_SYSTEM_ERROR;
goto out;
}
/* Success */
r = 0;
out:
sshbuf_free(b);
return r;
}
const char *

View 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.
@ -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 *);