summaryrefslogtreecommitdiff
path: root/sshkey.c
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 /sshkey.c
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
Diffstat (limited to 'sshkey.c')
-rw-r--r--sshkey.c174
1 files changed, 99 insertions, 75 deletions
diff --git a/sshkey.c b/sshkey.c
index 83985ca54..cfe598080 100644
--- a/sshkey.c
+++ b/sshkey.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshkey.c,v 1.18 2015/05/08 03:17:49 djm Exp $ */ 1/* $OpenBSD: sshkey.c,v 1.19 2015/05/21 04:55:51 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
4 * Copyright (c) 2008 Alexander von Gernler. All rights reserved. 4 * 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)
761 if (key == NULL) 761 if (key == NULL)
762 return SSH_ERR_INVALID_ARGUMENT; 762 return SSH_ERR_INVALID_ARGUMENT;
763 763
764 if (sshkey_is_cert(key)) {
765 if (key->cert == NULL)
766 return SSH_ERR_EXPECTED_CERT;
767 if (sshbuf_len(key->cert->certblob) == 0)
768 return SSH_ERR_KEY_LACKS_CERTBLOB;
769 }
764 type = force_plain ? sshkey_type_plain(key->type) : key->type; 770 type = force_plain ? sshkey_type_plain(key->type) : key->type;
765 typename = sshkey_ssh_name_from_type_nid(type, key->ecdsa_nid); 771 typename = sshkey_ssh_name_from_type_nid(type, key->ecdsa_nid);
766 772
@@ -1409,98 +1415,116 @@ sshkey_read(struct sshkey *ret, char **cpp)
1409} 1415}
1410 1416
1411int 1417int
1412sshkey_write(const struct sshkey *key, FILE *f) 1418sshkey_to_base64(const struct sshkey *key, char **b64p)
1413{ 1419{
1414 int ret = SSH_ERR_INTERNAL_ERROR; 1420 int r = SSH_ERR_INTERNAL_ERROR;
1415 struct sshbuf *b = NULL, *bb = NULL; 1421 struct sshbuf *b = NULL;
1416 char *uu = NULL; 1422 char *uu = NULL;
1423
1424 if (b64p != NULL)
1425 *b64p = NULL;
1426 if ((b = sshbuf_new()) == NULL)
1427 return SSH_ERR_ALLOC_FAIL;
1428 if ((r = sshkey_putb(key, b)) != 0)
1429 goto out;
1430 if ((uu = sshbuf_dtob64(b)) == NULL) {
1431 r = SSH_ERR_ALLOC_FAIL;
1432 goto out;
1433 }
1434 /* Success */
1435 if (b64p != NULL) {
1436 *b64p = uu;
1437 uu = NULL;
1438 }
1439 r = 0;
1440 out:
1441 sshbuf_free(b);
1442 free(uu);
1443 return r;
1444}
1445
1446static int
1447sshkey_format_rsa1(const struct sshkey *key, struct sshbuf *b)
1448{
1449 int r = SSH_ERR_INTERNAL_ERROR;
1417#ifdef WITH_SSH1 1450#ifdef WITH_SSH1
1418 u_int bits = 0; 1451 u_int bits = 0;
1419 char *dec_e = NULL, *dec_n = NULL; 1452 char *dec_e = NULL, *dec_n = NULL;
1420#endif /* WITH_SSH1 */
1421 1453
1422 if (sshkey_is_cert(key)) { 1454 if (key->rsa == NULL || key->rsa->e == NULL ||
1423 if (key->cert == NULL) 1455 key->rsa->n == NULL) {
1424 return SSH_ERR_EXPECTED_CERT; 1456 r = SSH_ERR_INVALID_ARGUMENT;
1425 if (sshbuf_len(key->cert->certblob) == 0) 1457 goto out;
1426 return SSH_ERR_KEY_LACKS_CERTBLOB;
1427 } 1458 }
1428 if ((b = sshbuf_new()) == NULL) 1459 if ((dec_e = BN_bn2dec(key->rsa->e)) == NULL ||
1429 return SSH_ERR_ALLOC_FAIL; 1460 (dec_n = BN_bn2dec(key->rsa->n)) == NULL) {
1430 switch (key->type) { 1461 r = SSH_ERR_ALLOC_FAIL;
1431#ifdef WITH_SSH1 1462 goto out;
1432 case KEY_RSA1: 1463 }
1433 if (key->rsa == NULL || key->rsa->e == NULL || 1464 /* size of modulus 'n' */
1434 key->rsa->n == NULL) { 1465 if ((bits = BN_num_bits(key->rsa->n)) <= 0) {
1435 ret = SSH_ERR_INVALID_ARGUMENT; 1466 r = SSH_ERR_INVALID_ARGUMENT;
1436 goto out; 1467 goto out;
1437 } 1468 }
1438 if ((dec_e = BN_bn2dec(key->rsa->e)) == NULL || 1469 if ((r = sshbuf_putf(b, "%u %s %s", bits, dec_e, dec_n)) != 0)
1439 (dec_n = BN_bn2dec(key->rsa->n)) == NULL) { 1470 goto out;
1440 ret = SSH_ERR_ALLOC_FAIL; 1471
1441 goto out; 1472 /* Success */
1442 } 1473 r = 0;
1443 /* size of modulus 'n' */ 1474 out:
1444 if ((bits = BN_num_bits(key->rsa->n)) <= 0) { 1475 if (dec_e != NULL)
1445 ret = SSH_ERR_INVALID_ARGUMENT; 1476 OPENSSL_free(dec_e);
1446 goto out; 1477 if (dec_n != NULL)
1447 } 1478 OPENSSL_free(dec_n);
1448 if ((ret = sshbuf_putf(b, "%u %s %s", bits, dec_e, dec_n)) != 0)
1449 goto out;
1450#endif /* WITH_SSH1 */ 1479#endif /* WITH_SSH1 */
1451 break; 1480
1452#ifdef WITH_OPENSSL 1481 return r;
1453 case KEY_DSA: 1482}
1454 case KEY_DSA_CERT_V00: 1483
1455 case KEY_DSA_CERT: 1484static int
1456 case KEY_ECDSA: 1485sshkey_format_text(const struct sshkey *key, struct sshbuf *b)
1457 case KEY_ECDSA_CERT: 1486{
1458 case KEY_RSA: 1487 int r = SSH_ERR_INTERNAL_ERROR;
1459 case KEY_RSA_CERT_V00: 1488 char *uu = NULL;
1460 case KEY_RSA_CERT: 1489
1461#endif /* WITH_OPENSSL */ 1490 if (key->type == KEY_RSA1) {
1462 case KEY_ED25519: 1491 if ((r = sshkey_format_rsa1(key, b)) != 0)
1463 case KEY_ED25519_CERT:
1464 if ((bb = sshbuf_new()) == NULL) {
1465 ret = SSH_ERR_ALLOC_FAIL;
1466 goto out;
1467 }
1468 if ((ret = sshkey_putb(key, bb)) != 0)
1469 goto out;
1470 if ((uu = sshbuf_dtob64(bb)) == NULL) {
1471 ret = SSH_ERR_ALLOC_FAIL;
1472 goto out; 1492 goto out;
1473 } 1493 } else {
1474 if ((ret = sshbuf_putf(b, "%s ", sshkey_ssh_name(key))) != 0) 1494 /* Unsupported key types handled in sshkey_to_base64() */
1495 if ((r = sshkey_to_base64(key, &uu)) != 0)
1475 goto out; 1496 goto out;
1476 if ((ret = sshbuf_put(b, uu, strlen(uu))) != 0) 1497 if ((r = sshbuf_putf(b, "%s %s",
1498 sshkey_ssh_name(key), uu)) != 0)
1477 goto out; 1499 goto out;
1478 break;
1479 default:
1480 ret = SSH_ERR_KEY_TYPE_UNKNOWN;
1481 goto out;
1482 } 1500 }
1501 r = 0;
1502 out:
1503 free(uu);
1504 return r;
1505}
1506
1507int
1508sshkey_write(const struct sshkey *key, FILE *f)
1509{
1510 struct sshbuf *b = NULL;
1511 int r = SSH_ERR_INTERNAL_ERROR;
1512
1513 if ((b = sshbuf_new()) == NULL)
1514 return SSH_ERR_ALLOC_FAIL;
1515 if ((r = sshkey_format_text(key, b)) != 0)
1516 goto out;
1483 if (fwrite(sshbuf_ptr(b), sshbuf_len(b), 1, f) != 1) { 1517 if (fwrite(sshbuf_ptr(b), sshbuf_len(b), 1, f) != 1) {
1484 if (feof(f)) 1518 if (feof(f))
1485 errno = EPIPE; 1519 errno = EPIPE;
1486 ret = SSH_ERR_SYSTEM_ERROR; 1520 r = SSH_ERR_SYSTEM_ERROR;
1487 goto out; 1521 goto out;
1488 } 1522 }
1489 ret = 0; 1523 /* Success */
1524 r = 0;
1490 out: 1525 out:
1491 if (b != NULL) 1526 sshbuf_free(b);
1492 sshbuf_free(b); 1527 return r;
1493 if (bb != NULL)
1494 sshbuf_free(bb);
1495 if (uu != NULL)
1496 free(uu);
1497#ifdef WITH_SSH1
1498 if (dec_e != NULL)
1499 OPENSSL_free(dec_e);
1500 if (dec_n != NULL)
1501 OPENSSL_free(dec_n);
1502#endif /* WITH_SSH1 */
1503 return ret;
1504} 1528}
1505 1529
1506const char * 1530const char *