version 1.336, 2019/07/15 13:16:29 |
version 1.337, 2019/07/16 13:18:39 |
|
|
#include "xmalloc.h" |
#include "xmalloc.h" |
#include "sshkey.h" |
#include "sshkey.h" |
#include "authfile.h" |
#include "authfile.h" |
#include "uuencode.h" |
|
#include "sshbuf.h" |
#include "sshbuf.h" |
#include "pathnames.h" |
#include "pathnames.h" |
#include "log.h" |
#include "log.h" |
|
|
static void |
static void |
do_convert_to_ssh2(struct passwd *pw, struct sshkey *k) |
do_convert_to_ssh2(struct passwd *pw, struct sshkey *k) |
{ |
{ |
size_t len; |
struct sshbuf *b; |
u_char *blob; |
char comment[61], *b64; |
char comment[61]; |
|
int r; |
int r; |
|
|
if ((r = sshkey_to_blob(k, &blob, &len)) != 0) |
if ((b = sshbuf_new()) == NULL) |
|
fatal("%s: sshbuf_new failed", __func__); |
|
if ((r = sshkey_putb(k, b)) != 0) |
fatal("key_to_blob failed: %s", ssh_err(r)); |
fatal("key_to_blob failed: %s", ssh_err(r)); |
|
if ((b64 = sshbuf_dtob64_string(b, 1)) == NULL) |
|
fatal("%s: sshbuf_dtob64_string failed", __func__); |
|
|
/* Comment + surrounds must fit into 72 chars (RFC 4716 sec 3.3) */ |
/* Comment + surrounds must fit into 72 chars (RFC 4716 sec 3.3) */ |
snprintf(comment, sizeof(comment), |
snprintf(comment, sizeof(comment), |
"%u-bit %s, converted by %s@%s from OpenSSH", |
"%u-bit %s, converted by %s@%s from OpenSSH", |
sshkey_size(k), sshkey_type(k), |
sshkey_size(k), sshkey_type(k), |
pw->pw_name, hostname); |
pw->pw_name, hostname); |
|
|
|
sshkey_free(k); |
|
sshbuf_free(b); |
|
|
fprintf(stdout, "%s\n", SSH_COM_PUBLIC_BEGIN); |
fprintf(stdout, "%s\n", SSH_COM_PUBLIC_BEGIN); |
fprintf(stdout, "Comment: \"%s\"\n", comment); |
fprintf(stdout, "Comment: \"%s\"\n%s", comment, b64); |
dump_base64(stdout, blob, len); |
|
fprintf(stdout, "%s\n", SSH_COM_PUBLIC_END); |
fprintf(stdout, "%s\n", SSH_COM_PUBLIC_END); |
sshkey_free(k); |
free(b64); |
free(blob); |
|
exit(0); |
exit(0); |
} |
} |
|
|
|
|
} |
} |
|
|
static struct sshkey * |
static struct sshkey * |
do_convert_private_ssh2_from_blob(u_char *blob, u_int blen) |
do_convert_private_ssh2(struct sshbuf *b) |
{ |
{ |
struct sshbuf *b; |
|
struct sshkey *key = NULL; |
struct sshkey *key = NULL; |
char *type, *cipher; |
char *type, *cipher; |
u_char e1, e2, e3, *sig = NULL, data[] = "abcde12345"; |
u_char e1, e2, e3, *sig = NULL, data[] = "abcde12345"; |
|
|
BIGNUM *dsa_pub_key = NULL, *dsa_priv_key = NULL; |
BIGNUM *dsa_pub_key = NULL, *dsa_priv_key = NULL; |
BIGNUM *rsa_n = NULL, *rsa_e = NULL, *rsa_d = NULL; |
BIGNUM *rsa_n = NULL, *rsa_e = NULL, *rsa_d = NULL; |
BIGNUM *rsa_p = NULL, *rsa_q = NULL, *rsa_iqmp = NULL; |
BIGNUM *rsa_p = NULL, *rsa_q = NULL, *rsa_iqmp = NULL; |
if ((b = sshbuf_from(blob, blen)) == NULL) |
|
fatal("%s: sshbuf_from failed", __func__); |
|
if ((r = sshbuf_get_u32(b, &magic)) != 0) |
if ((r = sshbuf_get_u32(b, &magic)) != 0) |
fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
|
|
if (magic != SSH_COM_PRIVATE_KEY_MAGIC) { |
if (magic != SSH_COM_PRIVATE_KEY_MAGIC) { |
error("bad magic 0x%x != 0x%x", magic, |
error("bad magic 0x%x != 0x%x", magic, |
SSH_COM_PRIVATE_KEY_MAGIC); |
SSH_COM_PRIVATE_KEY_MAGIC); |
sshbuf_free(b); |
|
return NULL; |
return NULL; |
} |
} |
if ((r = sshbuf_get_u32(b, &i1)) != 0 || |
if ((r = sshbuf_get_u32(b, &i1)) != 0 || |
|
|
if (strcmp(cipher, "none") != 0) { |
if (strcmp(cipher, "none") != 0) { |
error("unsupported cipher %s", cipher); |
error("unsupported cipher %s", cipher); |
free(cipher); |
free(cipher); |
sshbuf_free(b); |
|
free(type); |
free(type); |
return NULL; |
return NULL; |
} |
} |
|
|
} else if (strstr(type, "rsa")) { |
} else if (strstr(type, "rsa")) { |
ktype = KEY_RSA; |
ktype = KEY_RSA; |
} else { |
} else { |
sshbuf_free(b); |
|
free(type); |
free(type); |
return NULL; |
return NULL; |
} |
} |
|
|
fatal("%s: BN_new", __func__); |
fatal("%s: BN_new", __func__); |
if (!BN_set_word(rsa_e, e)) { |
if (!BN_set_word(rsa_e, e)) { |
BN_clear_free(rsa_e); |
BN_clear_free(rsa_e); |
sshbuf_free(b); |
|
sshkey_free(key); |
sshkey_free(key); |
return NULL; |
return NULL; |
} |
} |
|
|
} |
} |
rlen = sshbuf_len(b); |
rlen = sshbuf_len(b); |
if (rlen != 0) |
if (rlen != 0) |
error("do_convert_private_ssh2_from_blob: " |
error("%s: remaining bytes in key blob %d", __func__, rlen); |
"remaining bytes in key blob %d", rlen); |
|
sshbuf_free(b); |
|
|
|
/* try the key */ |
/* try the key */ |
if (sshkey_sign(key, &sig, &slen, data, sizeof(data), NULL, 0) != 0 || |
if (sshkey_sign(key, &sig, &slen, data, sizeof(data), NULL, 0) != 0 || |
|
|
int r, blen, escaped = 0; |
int r, blen, escaped = 0; |
u_int len; |
u_int len; |
char line[1024]; |
char line[1024]; |
u_char blob[8096]; |
struct sshbuf *buf; |
char encoded[8096]; |
char encoded[8096]; |
FILE *fp; |
FILE *fp; |
|
|
|
if ((buf = sshbuf_new()) == NULL) |
|
fatal("sshbuf_new failed"); |
if ((fp = fopen(identity_file, "r")) == NULL) |
if ((fp = fopen(identity_file, "r")) == NULL) |
fatal("%s: %s: %s", __progname, identity_file, strerror(errno)); |
fatal("%s: %s: %s", __progname, identity_file, strerror(errno)); |
encoded[0] = '\0'; |
encoded[0] = '\0'; |
|
|
(encoded[len-2] == '=') && |
(encoded[len-2] == '=') && |
(encoded[len-3] == '=')) |
(encoded[len-3] == '=')) |
encoded[len-3] = '\0'; |
encoded[len-3] = '\0'; |
blen = uudecode(encoded, blob, sizeof(blob)); |
if ((r = sshbuf_b64tod(buf, encoded)) != 0) |
if (blen < 0) |
fatal("%s: base64 decoding failed: %s", __func__, ssh_err(r)); |
fatal("uudecode failed."); |
|
if (*private) |
if (*private) |
*k = do_convert_private_ssh2_from_blob(blob, blen); |
*k = do_convert_private_ssh2(buf); |
else if ((r = sshkey_from_blob(blob, blen, k)) != 0) |
else if ((r = sshkey_fromb(buf, k)) != 0) |
fatal("decode blob failed: %s", ssh_err(r)); |
fatal("decode blob failed: %s", ssh_err(r)); |
fclose(fp); |
fclose(fp); |
} |
} |
|
|
} |
} |
if (n > SSHKEY_CERT_MAX_PRINCIPALS) |
if (n > SSHKEY_CERT_MAX_PRINCIPALS) |
fatal("Too many certificate principals specified"); |
fatal("Too many certificate principals specified"); |
|
|
tmp = tilde_expand_filename(argv[i], pw->pw_uid); |
tmp = tilde_expand_filename(argv[i], pw->pw_uid); |
if ((r = sshkey_load_public(tmp, &public, &comment)) != 0) |
if ((r = sshkey_load_public(tmp, &public, &comment)) != 0) |
fatal("%s: unable to open \"%s\": %s", |
fatal("%s: unable to open \"%s\": %s", |