/* XXX this is almost identical to sshkey_load_private_type() */ int sshkey_load_private(const char *filename, const char *passphrase, struct sshkey **keyp, char **commentp) { struct sshbuf *buffer = NULL; int r, fd; *keyp = NULL; if (commentp != NULL) *commentp = NULL; if ((fd = open(filename, O_RDONLY)) < 0) return SSH_ERR_SYSTEM_ERROR; if (sshkey_perm_ok(fd, filename) != 0) { r = SSH_ERR_KEY_BAD_PERMISSIONS; goto out; } if ((buffer = sshbuf_new()) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } if ((r = sshkey_load_file(fd, buffer)) != 0 || (r = sshkey_parse_private_fileblob(buffer, passphrase, filename, keyp, commentp)) != 0) goto out; r = 0; out: close(fd); if (buffer != NULL) sshbuf_free(buffer); return r; }
struct sshbuf * load_file(const char *name) { int fd; struct sshbuf *ret; ASSERT_PTR_NE(ret = sshbuf_new(), NULL); ASSERT_INT_NE(fd = open(test_data_file(name), O_RDONLY), -1); ASSERT_INT_EQ(sshkey_load_file(fd, name, ret), 0); close(fd); return ret; }
/* XXX kill perm_ok now that we have SSH_ERR_KEY_BAD_PERMISSIONS? */ int sshkey_load_private_type(int type, const char *filename, const char *passphrase, struct sshkey **keyp, char **commentp, int *perm_ok) { int fd, r; struct sshbuf *buffer = NULL; *keyp = NULL; if (commentp != NULL) *commentp = NULL; if ((fd = open(filename, O_RDONLY)) < 0) { if (perm_ok != NULL) *perm_ok = 0; return SSH_ERR_SYSTEM_ERROR; } if (!sshkey_perm_ok(fd, filename)) { if (perm_ok != NULL) *perm_ok = 0; r = SSH_ERR_KEY_BAD_PERMISSIONS; goto out; } if (perm_ok != NULL) *perm_ok = 1; if ((buffer = sshbuf_new()) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } if ((r = sshkey_load_file(fd, filename, buffer)) != 0) goto out; if ((r = sshkey_parse_private_type(buffer, type, passphrase, keyp, commentp)) != 0) goto out; r = 0; out: close(fd); if (buffer != NULL) sshbuf_free(buffer); return r; }
/* * Loads the public part of the ssh v1 key file. Returns NULL if an error was * encountered (the file does not exist or is not readable), and the key * otherwise. */ static int sshkey_load_public_rsa1(int fd, struct sshkey **keyp, char **commentp) { struct sshbuf *b = NULL; int r; *keyp = NULL; if (commentp != NULL) *commentp = NULL; if ((b = sshbuf_new()) == NULL) return SSH_ERR_ALLOC_FAIL; if ((r = sshkey_load_file(fd, b)) != 0) goto out; if ((r = sshkey_parse_public_rsa1_fileblob(b, keyp, commentp)) != 0) goto out; r = 0; out: sshbuf_free(b); return r; }
/* * Loads the public part of the ssh v1 key file. Returns NULL if an error was * encountered (the file does not exist or is not readable), and the key * otherwise. */ static int sshkey_load_public_rsa1(int fd, const char *filename, struct sshkey **keyp, char **commentp) { struct sshbuf *buffer = NULL; int r; *keyp = NULL; if (commentp != NULL) *commentp = NULL; if ((buffer = sshbuf_new()) == NULL) return SSH_ERR_ALLOC_FAIL; if ((r = sshkey_load_file(fd, filename, buffer)) != 0) goto out; if ((r = sshkey_parse_public_rsa1(buffer, keyp, commentp)) != 0) goto out; r = 0; out: sshbuf_free(buffer); return r; }
int sshkey_load_private_type_fd(int fd, int type, const char *passphrase, struct sshkey **keyp, char **commentp) { struct sshbuf *buffer = NULL; int r; if ((buffer = sshbuf_new()) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } if ((r = sshkey_load_file(fd, buffer)) != 0 || (r = sshkey_parse_private_fileblob_type(buffer, type, passphrase, keyp, commentp)) != 0) goto out; /* success */ r = 0; out: if (buffer != NULL) sshbuf_free(buffer); return r; }
int sshkey_load_private_pem(int fd, int type, const char *passphrase, struct sshkey **keyp, char **commentp) { struct sshbuf *buffer = NULL; int r; *keyp = NULL; if (commentp != NULL) *commentp = NULL; if ((buffer = sshbuf_new()) == NULL) return SSH_ERR_ALLOC_FAIL; if ((r = sshkey_load_file(fd, NULL, buffer)) != 0) goto out; if ((r = sshkey_parse_private_pem(buffer, type, passphrase, keyp, commentp)) != 0) goto out; r = 0; out: sshbuf_free(buffer); return r; }
int main(int argc, char **argv) { int ch, fd, r; int count_flag = 0, dump_flag = 0, replace_flag = 0; int packet_index = -1, direction = -1; int s2c = 0, c2s = 0; /* packet counts */ const char *kex = NULL, *kpath = NULL, *data_path = NULL; struct sshkey *key = NULL; struct sshbuf *replace_data = NULL; setvbuf(stdout, NULL, _IONBF, 0); while ((ch = getopt(argc, argv, "hcdrvD:f:K:k:i:")) != -1) { switch (ch) { case 'h': usage(); return 0; case 'c': count_flag = 1; break; case 'd': dump_flag = 1; break; case 'r': replace_flag = 1; break; case 'v': do_debug = 1; break; case 'D': if (strcasecmp(optarg, "s2c") == 0) direction = S2C; else if (strcasecmp(optarg, "c2s") == 0) direction = C2S; else badusage("Invalid direction (-D)"); break; case 'f': data_path = optarg; break; case 'K': kex = optarg; break; case 'k': kpath = optarg; break; case 'i': packet_index = atoi(optarg); if (packet_index < 0) badusage("Invalid packet index"); break; default: badusage("unsupported flag"); } } argc -= optind; argv += optind; /* Must select a single mode */ if ((count_flag + dump_flag + replace_flag) != 1) badusage("Must select one mode: -c, -d or -r"); /* KEX type is mandatory */ if (kex == NULL || !kex_names_valid(kex) || strchr(kex, ',') != NULL) badusage("Missing or invalid kex type (-K flag)"); /* Valid key is mandatory */ if (kpath == NULL) badusage("Missing private key (-k flag)"); if ((fd = open(kpath, O_RDONLY)) == -1) err(1, "open %s", kpath); if ((r = sshkey_load_private_type_fd(fd, KEY_UNSPEC, NULL, &key, NULL)) != 0) errx(1, "Unable to load key %s: %s", kpath, ssh_err(r)); close(fd); /* XXX check that it is a private key */ /* XXX support certificates */ if (key == NULL || key->type == KEY_UNSPEC || key->type == KEY_RSA1) badusage("Invalid key file (-k flag)"); /* Replace (fuzz) mode */ if (replace_flag) { if (packet_index == -1 || direction == -1 || data_path == NULL) badusage("Replace (-r) mode must specify direction " "(-D) packet index (-i) and data path (-f)"); if ((fd = open(data_path, O_RDONLY)) == -1) err(1, "open %s", data_path); replace_data = sshbuf_new(); if ((r = sshkey_load_file(fd, replace_data)) != 0) errx(1, "read %s: %s", data_path, ssh_err(r)); close(fd); } /* Dump mode */ if (dump_flag) { if (packet_index == -1 || direction == -1 || data_path == NULL) badusage("Dump (-d) mode must specify direction " "(-D), packet index (-i) and data path (-f)"); } /* Count mode needs no further flags */ do_kex_with_key(kex, key, &c2s, &s2c, direction, packet_index, dump_flag ? data_path : NULL, replace_flag ? replace_data : NULL); sshkey_free(key); sshbuf_free(replace_data); if (count_flag) { printf("S2C: %d\n", s2c); printf("C2S: %d\n", c2s); } return 0; }