openssh/openssh-6.5p1-key-converter.patch
Petr Cerny 08f9072513 Accepting request 222365 from home:pcerny:factory
- Update of the underlying OpenSSH to 6.5p1

- Update to 6.5p1
  Features since 6.4p1:
  * ssh(1), sshd(8): support for key exchange using ECDH in
    Daniel Bernstein's Curve25519; default when both the client
    and server support it.
  * ssh(1), sshd(8): support for Ed25519 as a public key type fo
    rboth server and client.  Ed25519 is an EC signature offering
    better security than ECDSA and DSA and good performance.
  * Add a new private key format that uses a bcrypt KDF to better
    protect keys at rest. Used unconditionally for Ed25519 keys,
    on demand for other key types via the -o ssh-keygen(1)
    option.  Intended to become default in the near future.
    Details documented in PROTOCOL.key.
  * ssh(1), sshd(8): new transport cipher
    "chacha20-poly1305@openssh.com" combining Daniel Bernstein's
    ChaCha20 stream cipher and Poly1305 MAC to build an
    authenticated encryption mode. Details documented
    PROTOCOL.chacha20poly1305.
  * ssh(1), sshd(8): refuse RSA keys from old proprietary clients
    and servers that use the obsolete RSA+MD5 signature scheme.
    It will still be possible to connect with these
    clients/servers but only DSA keys will be accepted, and
    OpenSSH will refuse connection entirely in a future release.
  * ssh(1), sshd(8): refuse old proprietary clients and servers
    that use a weaker key exchange hash calculation.
  * ssh(1): increase the size of the Diffie-Hellman groups
    requested for each symmetric key size. New values from NIST
    Special Publication 800-57 with the upper limit specified by

OBS-URL: https://build.opensuse.org/request/show/222365
OBS-URL: https://build.opensuse.org/package/show/network/openssh?expand=0&rev=63
2014-02-14 14:54:10 +00:00

535 lines
13 KiB
Diff

# SSHv1 to SSHv2 RSA keys converter
diff --git a/openssh-6.5p1/converter/Makefile b/openssh-6.5p1/converter/Makefile
new file mode 100644
--- /dev/null
+++ b/openssh-6.5p1/converter/Makefile
@@ -0,0 +1,17 @@
+
+bindir=/usr/bin
+mandir=/usr/share/man
+
+all : ssh-keyconverter
+
+ssh-keyconverter.o: ssh-keyconverter.c ../key.h ../authfile.h ../misc.h ../xmalloc.h
+ gcc $(RPM_OPT_FLAGS) -c -I../ $< -o $@
+
+ssh-keyconverter: ssh-keyconverter.o ../libssh.a ../openbsd-compat/libopenbsd-compat.a
+ gcc $< -Wl,--no-as-needed $(RPM_OPT_FLAGS) -L../ -L../openbsd-compat/ -lcrypto -lssh -lopenbsd-compat -lssh -lopenbsd-compat -lpam -ldl -lwrap -lutil -lz -lnsl -lcrypt -lssl -o $@
+
+install: ssh-keyconverter ssh-keyconverter.1
+ if [ ! -d $(DESTDIR)$(bindir) ]; then install -d -m 755 $(DESTDIR)$(bindir); fi
+ install -m 755 ssh-keyconverter $(DESTDIR)$(bindir)
+ if [ ! -d $(DESTDIR)$(mandir)/man1 ]; then install -d -m 755 $(DESTDIR)$(mandir)/man1; fi
+ install -m 644 ssh-keyconverter.1 $(DESTDIR)$(mandir)/man1
diff --git a/openssh-6.5p1/converter/ssh-keyconverter.1 b/openssh-6.5p1/converter/ssh-keyconverter.1
new file mode 100644
--- /dev/null
+++ b/openssh-6.5p1/converter/ssh-keyconverter.1
@@ -0,0 +1,155 @@
+.\" Manpage for ssh-keyconverter
+.\"
+.Dd February 2, 2002
+.Dt SSH-KEYCONVER 1
+.Os
+.Sh NAME
+.Nm ssh-keyconvert
+.Nd convert ssh v1 keys and authorization files
+.Sh SYNOPSIS
+.Nm ssh-keyconvert
+.Op Fl k
+.Op Fl o Ar output_file
+.Ar identity_file ...
+.Nm ssh-keyconvert
+.Op Fl a
+.Op Fl o Ar output_file
+.Ar authorization_file ...
+.Sh DESCRIPTION
+.Nm
+converts RSA public and private keys used for public key based
+user authentication with protocol version 1 to the format
+used with protocol version 2.
+.Pp
+When using RSA user authentication with SSH protocol version 1,
+the client uses the private key from
+.Pa $HOME/.ssh/identity
+to provide its identity to the server. The server grants or denies
+access based on whether the public part of this key is listed in
+.Pa $HOME/.ssh/authorized_keys .
+.Pp
+SSH protocol version 2 supports both DSA and RSA keys, but the
+way RSA keys are stored are differently. On the client, the default
+file name is
+.Pa .ssh/id_rsa
+rather than
+.Pa .ssh/identity ,
+and the file's format is different as well. On the server, the
+public porting of the key can still be stored in
+.Pa .ssh/authorized_keys ,
+but the key notation has changed as well.
+Therefore, when switching from protocol version 1
+to version 2, you either have to create a new identity key using
+.Xr ssh-keygen 1
+and add that key to the server's
+.Pa authorized_keys
+file, or you need to convert your keys using
+.Nm ssh-keyconvert .
+.Pp
+By default,
+.Nm
+will try to guess the type of file that is to be converted.
+If it fails to guess correctly, you can tell if what type of
+conversion to perform by specifying the
+.Fl k
+option to convert the private key, or the
+.Fl a
+option to convert an authorisation file.
+.Pp
+When converting your private keys stored in
+.Pa .ssh/identity ,
+.Nm
+will read the private key, prompting you for the pass phrase
+if the key is protected by a pass phrase. If the
+.Fl o
+option is given, it will write the private key to the specified
+file, using version 2 syntax. If the key was protected by a
+pass phrase, it will use the same pass phrase to protect the new
+file.
+It will also write the public portion of the key to a second file,
+using the specified file name with
+.Dq .pub
+appended.
+If the
+.Fl o
+option was not given, private and public key will be written to
+.Pa id_rsa
+and
+.Pa id_rsa.pub ,
+respectively, relative to the directory of the input key file.
+.Pp
+If the destination file already exists,
+.Nm
+will prompt the user for confirmation before overwriting the
+file, unless the
+.Fl f
+option is given.
+.Pp
+When converting your
+.Pa authorized_keys
+file,
+.Nm
+will ignore any keys in SSH version 2 format. Any public keys
+in version 1 format will be converted and appended to the output file
+using the new syntax. If the
+.Fl o
+option is given, keys are appended to the specified file. If it
+is not given,
+.Nm
+will append all keys to the input file.
+.Pp
+Note that
+.Nm
+does not check for duplicate keys, so if you run it on
+.Pa .ssh/authorized_keys
+more several times, the converted keys will show up several times.
+.Sh OPTIONS
+.Bl -tag -width Ds
+.It Fl k
+Convert private key file(s). The default is to guess the
+type of file that should be converted.
+.It Fl a
+Convert
+.Pa authorized_keys
+file(s). The default is to guess the
+type of file that should be converted.
+.It Fl o Ar outfile
+Specify the name of the output file.
+When converting an authorization file, all public keys will
+be appended to this file.
+For private key conversion, the private and public components of
+the key will be stored in
+.Pa outfile
+and
+.Pa outfile.pub ,
+respectively.
+Note that since every key must be stored in a separate file, you
+cannot use this option when you specify several input files.
+.It Fl f
+When converting a key file, and the output file already exists,
+.Nm
+will ask the user whether to overwrite the file. Using this option
+forces overwriting.
+.El
+.Sh AUTHORS
+OpenSSH is a derivative of the original and free
+ssh 1.2.12 release by Tatu Ylonen.
+Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos,
+Theo de Raadt and Dug Song
+removed many bugs, re-added newer features and
+created OpenSSH.
+.Nm
+was contributed by Olaf Kirch.
+.Sh SEE ALSO
+.Xr ssh 1 ,
+.Xr ssh-add 1 ,
+.Xr ssh-agent 1 ,
+.Xr sshd 8
+.Rs
+.%A J. Galbraith
+.%A R. Thayer
+.%T "SECSH Public Key File Format"
+.%N draft-ietf-secsh-publickeyfile-01.txt
+.%D March 2001
+.%O work in progress material
+.Re
diff --git a/openssh-6.5p1/converter/ssh-keyconverter.c b/openssh-6.5p1/converter/ssh-keyconverter.c
new file mode 100644
--- /dev/null
+++ b/openssh-6.5p1/converter/ssh-keyconverter.c
@@ -0,0 +1,345 @@
+/*
+ * SSH v1 to v2 RSA key converter.
+ *
+ * Instead of a manpage:
+ *
+ * ssh-keyconverter ~/.ssh/identity
+ * will put the old RSA key in ~/.ssh/id_rsa and id_rsa.pub
+ * If a "-o foofah" is given, the keys will be written to
+ * foofah and foofah.pub, respectively.
+ *
+ * ssh-keyconverter ~/.ssh/authorized_keys
+ * will convert all old RSA keys and add them to the
+ * input file. The -o foofah option will direct
+ * output to a different file.
+ * (Note that it's harmless to specify the same file
+ * as input and output, as ssh-keyconverter will ignore
+ * any v2 keys, and output is always appended, never
+ * replacing the original file).
+ *
+ * To compile:
+ *
+ * gcc -g -Wall -o ssh-keyconverter converter.c \
+ * -L. -Lopenbsd-compat/ -lssh -lopenbsd-compat -lssh \
+ * -lpam -ldl -lwrap -lutil -lz -lnsl \
+ * -Wl,-Bstatic -lcrypto -Wl,-dy
+ *
+ * Enjoy. --okir
+ */
+
+#include <stdio.h>
+#include <getopt.h>
+#include <string.h>
+#include <sys/param.h>
+#include <unistd.h>
+#include "key.h"
+#include "authfile.h"
+#include "misc.h"
+#include "xmalloc.h"
+
+#define TYPE_KEY 0
+#define TYPE_AUTHKEYS 1
+
+#define PASSPHRASE_ATTEMPTS 3
+
+static int opt_verbose = 0;
+static int opt_force = 0;
+
+static void convert(int, const char *, const char *);
+static void convert_private_key(const char *, const char *);
+static void convert_authorized_keys(const char *, const char *);
+static int fileok(const char *, char *, size_t);
+static int guess_type(const char *);
+
+int
+main(int argc, char **argv)
+{
+ int opt_type = -1;
+ char *opt_outfile = NULL;
+ int c;
+
+ while ((c = getopt(argc, argv, "afko:")) != -1) {
+ switch (c) {
+ case 'a':
+ opt_type = TYPE_AUTHKEYS;
+ break;
+ case 'f':
+ opt_force = 1;
+ break;
+ case 'k':
+ opt_type = TYPE_KEY;
+ break;
+ case 'o':
+ opt_outfile = optarg;
+ break;
+ case 'v':
+ opt_verbose++;
+ break;
+ default:
+ fprintf(stderr,
+ "usage: ssh-keyconvert [-a | -k] "
+ "[-o filename] [-v] ...\n");
+ exit(1);
+ }
+ }
+
+ /* Warning, nanny code follows */
+#if 0
+ if (opt_outfile && (argc - optind) > 1 && opt_type != TYPE_AUTHKEY) {
+ fprintf(stderr,
+ "Output file ambiguous: more than two "
+ "input files given. Abort.\n");
+ exit(1);
+ }
+#endif
+
+ if (optind == argc) {
+ fprintf(stderr,
+ "Missing input file(s).\n");
+ exit(1);
+ }
+
+ for (; optind < argc; optind++) {
+ char *name = argv[optind];
+ int type;
+
+ if ((type = opt_type) < 0)
+ type = guess_type(name);
+ convert(type, name, opt_outfile);
+ }
+
+ return 0;
+}
+
+static void
+convert(int type, const char *iname, const char *oname)
+{
+ if (type == TYPE_KEY) {
+ convert_private_key(iname, oname);
+ } else if (type == TYPE_AUTHKEYS) {
+ convert_authorized_keys(iname, oname);
+ } else {
+ fprintf(stderr,
+ "Conversion type not yet implemented.\n");
+ exit(1);
+ }
+}
+
+static void
+convert_private_key(const char *iname, const char *oname)
+{
+ char prompt[1024], privname[PATH_MAX], pubname[PATH_MAX];
+ char *comment = NULL, *passphrase;
+ Key *key = NULL, *pk = NULL;
+ int i;
+ FILE *pf = NULL;
+
+ passphrase = xstrdup("");
+ snprintf(prompt, sizeof(prompt),
+ "Enter passphrase for key '%.100s': ",iname);
+ for (i = 0; !key && i < PASSPHRASE_ATTEMPTS; i++) {
+ if (i) {
+ /* Zap old pass phrase */
+ memset(passphrase, 0, strlen(passphrase));
+ free(passphrase);
+
+ /* Get a pass phrase from the user */
+ passphrase = read_passphrase(prompt, 0);
+ }
+ key = key_load_private(iname, passphrase, &comment);
+ if (!key && i)
+ printf("Bad passphrase, please try again.\n");
+ }
+
+ if (oname != NULL) {
+ strcpy(privname, oname);
+ } else {
+ const char *s;
+
+ if ((s = strrchr(iname, '/')) != NULL) {
+ int n = s + 1 - iname;
+
+ strncpy(privname, iname, n);
+ privname[n++] = '\0';
+ }
+ strcat(privname, "id_rsa");
+ }
+
+ if (!fileok("private", privname, sizeof(privname)))
+ goto out;
+
+ sprintf(pubname, "%s.pub", privname);
+ if (!fileok("public", pubname, sizeof(pubname)))
+ goto out;
+
+ /* "convert" from RSA1 to RSA */
+ key->type = KEY_RSA;
+ pk = key_from_private(key);
+
+ /* Now write the key in earnest */
+ if (!key_save_private(key, privname, passphrase, comment)) {
+ fprintf(stderr,
+ "Failed to save private key to %s: %m.\n", privname);
+ goto out;
+ }
+
+ if (!(pf = fopen(pubname, "w"))) {
+ fprintf(stderr,
+ "Failed to save public key to %s: %m.\n", pubname);
+ goto out;
+ }
+ if (!key_write(pk, pf)) {
+ fprintf(stderr,
+ "Failed to save public key to %s: %m.\n", pubname);
+ goto out;
+ }
+ if (comment)
+ fprintf(pf, " %s\n", comment);
+
+out:
+ memset(passphrase, 0, strlen(passphrase));
+ free(passphrase);
+ if (key)
+ key_free(key);
+ if (pk)
+ key_free(pk);
+ if (pf)
+ fclose(pf);
+}
+
+static void
+convert_authorized_keys(const char *iname, const char *oname)
+{
+ char line[1024];
+ FILE *ifp, *ofp;
+ Key *key;
+
+ if (!(ifp = fopen(iname, "r"))) {
+ perror(iname);
+ exit(1);
+ }
+
+ if (oname == NULL)
+ oname = iname;
+
+ if (!strcmp(oname, "-")) {
+ ofp = stdout;
+ } else {
+ if ((ofp = fopen(oname, "a")) == NULL) {
+ perror(oname);
+ exit(1);
+ }
+ }
+ setlinebuf(ofp);
+
+#define whitespace(c) ((c) == ' ' || (c) == '\t')
+ while (fgets(line, sizeof(line), ifp) != NULL) {
+ char *cp = line, *options = NULL;
+
+ while (whitespace(*cp))
+ cp++;
+ if (!*cp || *cp == '\n' || *cp == '#')
+ continue;
+
+ key = key_new(KEY_RSA1);
+ if (key_read(key, &cp) != 1) {
+ /* Skip options, if any */
+ int quoted = 0;
+
+ options = cp;
+ for (; *cp && (quoted || !whitespace(*cp)); cp++) {
+ if (cp[0] == '\\' && cp[1] == '"')
+ ++cp;
+ else if (*cp == '"')
+ quoted = !quoted;
+ }
+ if (quoted)
+ goto next;
+ *cp++ = '\0';
+ while (whitespace(*cp))
+ cp++;
+ if (key_read(key, &cp) != 1)
+ goto next;
+ }
+
+ if (options)
+ fprintf(ofp, "%s ", options);
+ /* "convert" from RSA1 to RSA */
+ key->type = KEY_RSA;
+ key_write(key, ofp);
+ fputs(cp, ofp);
+ key_free(key);
+
+ next:
+ ;
+ }
+}
+
+/* if file exists, ask user whether to overwrite it */
+static int
+fileok(const char *what, char *filename, size_t size)
+{
+ char buffer[PATH_MAX];
+ int n;
+
+checkagain:
+ if (access(filename, F_OK) < 0)
+ return 1;
+ printf("%s key file %s already exists.\n", what, filename);
+ if (opt_force) {
+ printf("Overwriting because of -f option...\n");
+ return 1;
+ }
+
+tryagain:
+ printf("Please enter a different filename, "
+ "or return to overwrite: ");
+ fflush(stdout);
+
+ n = read(0, buffer, sizeof(buffer)-1);
+ if (n <= 0)
+ printf("\n");
+ if (n < 0) {
+ perror("read failed");
+ exit(1);
+ }
+ if (n == 0) {
+ fprintf(stderr, "EOF from standard input. Bye.\n");
+ exit(1);
+ }
+ buffer[n] = '\0';
+ while (n && buffer[n-1] == '\n')
+ buffer[--n] = '\0';
+ if (n == 0)
+ return 1;
+ if (n >= size) {
+ fprintf(stderr, "Filename too long.\n");
+ goto tryagain;
+ }
+ strcpy(filename, buffer);
+ goto checkagain;
+}
+
+/*
+ * Guess the type of file to be converted.
+ * XXX: should look at the file; v1 key files
+ * start with "SSH PRIVATE KEY FILE"
+ */
+static int
+guess_type(const char *name)
+{
+ printf("%s... ", name);
+ if (strstr(name, "identity")) {
+ printf("looks like a key file\n");
+ return TYPE_KEY;
+ }
+ if (strstr(name, "authorized_keys")) {
+ printf("looks like an authorized_keys file\n");
+ return TYPE_AUTHKEYS;
+ }
+
+ if (opt_verbose)
+ printf("unable to identify.");
+ fprintf(stderr, "Please specify the file type for %s. Abort.\n", name);
+ exit(1);
+}