diff options
-rw-r--r-- | sshkey.c | 174 | ||||
-rw-r--r-- | sshkey.h | 3 |
2 files changed, 101 insertions, 76 deletions
@@ -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 | ||
1411 | int | 1417 | int |
1412 | sshkey_write(const struct sshkey *key, FILE *f) | 1418 | sshkey_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 | |||
1446 | static int | ||
1447 | sshkey_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: | 1484 | static int |
1456 | case KEY_ECDSA: | 1485 | sshkey_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 | |||
1507 | int | ||
1508 | sshkey_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 | ||
1506 | const char * | 1530 | const char * |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshkey.h,v 1.5 2015/01/26 02:59:11 djm Exp $ */ | 1 | /* $OpenBSD: sshkey.h,v 1.6 2015/05/21 04:55:51 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. | 4 | * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. |
@@ -163,6 +163,7 @@ int sshkey_from_blob(const u_char *, size_t, struct sshkey **); | |||
163 | int sshkey_fromb(struct sshbuf *, struct sshkey **); | 163 | int sshkey_fromb(struct sshbuf *, struct sshkey **); |
164 | int sshkey_froms(struct sshbuf *, struct sshkey **); | 164 | int sshkey_froms(struct sshbuf *, struct sshkey **); |
165 | int sshkey_to_blob(const struct sshkey *, u_char **, size_t *); | 165 | int sshkey_to_blob(const struct sshkey *, u_char **, size_t *); |
166 | int sshkey_to_base64(const struct sshkey *, char **); | ||
166 | int sshkey_putb(const struct sshkey *, struct sshbuf *); | 167 | int sshkey_putb(const struct sshkey *, struct sshbuf *); |
167 | int sshkey_puts(const struct sshkey *, struct sshbuf *); | 168 | int sshkey_puts(const struct sshkey *, struct sshbuf *); |
168 | int sshkey_plain_to_blob(const struct sshkey *, u_char **, size_t *); | 169 | int sshkey_plain_to_blob(const struct sshkey *, u_char **, size_t *); |