Lars Nordin
2012-Sep-09 18:54 UTC
Patch for ssh-keygen to allow conversion of public key to openssh format
Hi, I needed to convert a public RSA key to autorized_keys format and found ssh-keygen lacking this feature. I made the option -Q publicfile to allow an conversion like ssh-keygen -Q pubrsa.pem -y The patch is produced using unified diff and made on latest release. If you like it and can make a patch for the man-page also! Regards, /Lars -------------- next part -------------- diff -u openssh-6.1p1/authfile.c openssh-6.1p1-lano/authfile.c --- openssh-6.1p1/authfile.c 2012-02-10 22:19:02.000000000 +0100 +++ openssh-6.1p1-lano/authfile.c 2012-09-08 11:59:08.000000000 +0200 @@ -792,6 +792,58 @@ return 0; } +Key * +key_load_public_pem(char *filename, char **commentp) +{ + FILE *fp = NULL; + EVP_PKEY *pk = NULL; + X509 *x = NULL; + Key *pub = NULL; + char *name = "<no key>"; + + fp = fopen(filename, "r"); + if (fp == NULL) { + error("fopen of %s failed: %s", filename, strerror(errno)); + return NULL; + } + x = PEM_read_X509(fp, NULL, NULL, NULL); + if (x == NULL) { + debug3("Not X509 format, try public key format"); + rewind(fp); + pk = PEM_read_PUBKEY(fp, NULL, NULL, NULL); + } else { + pk = X509_get_pubkey(x); + } + if (pk == NULL) { + debug("PEM_read_PUBKEY() file %s failed", filename); + debug3("%s", ERR_error_string(ERR_get_error(), NULL)); + if (x != NULL) + X509_free(x); + return NULL; + } else { + pub = key_new(KEY_UNSPEC); + pub->rsa = RSAPublicKey_dup(EVP_PKEY_get1_RSA(pk)); + pub->type = KEY_RSA; + name = "rsa w/o comment"; +#ifdef DEBUG_PK + RSA_print_fp(stderr, prv->rsa, 8); +#endif + } + + fclose(fp); + + if (pk != NULL) + EVP_PKEY_free(pk); + if (x != NULL) + X509_free(x); + + if (pub != NULL && commentp) + *commentp = xstrdup(name); + debug("read PEM public key done: type %s", + pub ? key_type(pub) : "<unknown>"); + return pub; +} + /* load public key from ssh v1 private or any pubkey file */ Key * key_load_public(const char *filename, char **commentp) @@ -799,6 +851,11 @@ Key *pub; char file[MAXPATHLEN]; + /* try PEM public */ + pub = key_load_public_pem(filename, commentp); + if (pub != NULL) + return pub; + /* try rsa1 private key */ pub = key_load_public_type(KEY_RSA1, filename, commentp); if (pub != NULL) diff -u openssh-6.1p1/config.status openssh-6.1p1-lano/config.status --- openssh-6.1p1/config.status 2012-09-07 11:01:15.000000000 +0200 +++ openssh-6.1p1-lano/config.status 2012-09-08 11:59:38.000000000 +0200 @@ -445,7 +445,7 @@ This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." -ac_pwd='/work/src/openssh-6.1p1' +ac_pwd='/work/src/openssh-6.1p1-lano' srcdir='.' INSTALL='/usr/bin/install -c' AWK='gawk' Common subdirectories: openssh-6.1p1/contrib and openssh-6.1p1-lano/contrib Common subdirectories: openssh-6.1p1/openbsd-compat and openssh-6.1p1-lano/openbsd-compat Common subdirectories: openssh-6.1p1/regress and openssh-6.1p1-lano/regress Common subdirectories: openssh-6.1p1/scard and openssh-6.1p1-lano/scard diff -u openssh-6.1p1/ssh-keygen.c openssh-6.1p1-lano/ssh-keygen.c --- openssh-6.1p1/ssh-keygen.c 2012-07-31 04:20:44.000000000 +0200 +++ openssh-6.1p1-lano/ssh-keygen.c 2012-09-07 09:26:01.000000000 +0200 @@ -141,6 +141,7 @@ } convert_format = FMT_RFC4716; int print_public = 0; int print_generic = 0; +int read_public_only = 0; char *key_type_name = NULL; @@ -240,6 +241,13 @@ char *pass; Key *prv; + if (read_public_only) { + Key *pub; + + pub = key_load_public(filename, NULL); + return pub; + } + prv = key_load_private(filename, "", NULL); if (prv == NULL) { if (identity_passphrase) @@ -705,7 +713,13 @@ perror(identity_file); exit(1); } - prv = load_identity(identity_file); + + if (read_public_only == 1) { + prv = key_load_public(identity_file, NULL); + } else { + prv = load_identity(identity_file); + } + if (prv == NULL) { fprintf(stderr, "load failed\n"); exit(1); @@ -1963,7 +1977,7 @@ } while ((opt = getopt(argc, argv, "AegiqpclBHLhvxXyF:b:f:t:D:I:J:j:K:P:" - "m:N:n:O:C:r:g:R:T:G:M:S:s:a:V:W:z")) != -1) { + "m:N:n:O:C:r:g:R:T:G:M:S:s:a:V:W:zQ:")) != -1) { switch (opt) { case 'A': gen_all_hostkeys = 1; @@ -2129,6 +2143,14 @@ if (BN_hex2bn(&start, optarg) == 0) fatal("Invalid start point."); break; + case 'Q': + if (strlcpy(identity_file, optarg, sizeof(identity_file)) >+ sizeof(identity_file)) + fatal("Identity filename too long"); + have_identity = 1; + print_public = 1; + read_public_only = 1; + break; case 'V': parse_cert_times(optarg); break;
Damien Miller
2012-Sep-10 03:36 UTC
Patch for ssh-keygen to allow conversion of public key to openssh format
On Sun, 9 Sep 2012, Lars Nordin wrote:> Hi, > > I needed to convert a public RSA key to autorized_keys format and found > ssh-keygen lacking this feature. > > I made the option -Q publicfile to allow an conversion like > ssh-keygen -Q pubrsa.pem -y > > The patch is produced using unified diff and made on latest release.I think you can do this already: [djm at fuyu ~]$ openssl genrsa 1024 > /tmp/k.key Generating RSA private key, 1024 bit long modulus ..........................++++++ ............................................++++++ e is 65537 (0x10001) [djm at fuyu ~]$ openssl rsa -pubout < /tmp/k.key > /tmp/k.pub writing RSA key [djm at fuyu ~]$ cat /tmp/k.pub -----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCU7vN7q9f9bHiAYdxvyyGAwGgS LmVxczjf8V+YArEIcAuv8hHR4PkvXS4oWBJyUlNbRxr419NLAVcHmo1Pdnnxqan+ p2HO5n16Syy9eKtJ2/SKYjJlTDh9EdR3Xr2uDYziDcpT30EIhUn9soAX21lILaxo RFmlsTOOnXFwf9PweQIDAQAB -----END PUBLIC KEY----- [djm at fuyu ~]$ ssh-keygen -i -f /tmp/k.pub -m pkcs8 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQCU7vN7q9f9bHiAYdxvyyGAwGgSLmVxczjf8V+YArEIcAuv8hHR4PkvXS4oWBJyUlNbRxr419NLAVcHmo1Pdnnxqan+p2HO5n16Syy9eKtJ2/SKYjJlTDh9EdR3Xr2uDYziDcpT30EIhUn9soAX21lILaxoRFmlsTOOnXFwf9PweQ= -d
Lars Nordin
2012-Sep-10 05:23 UTC
Patch for ssh-keygen to allow conversion of public key to openssh format
On 2012-09-10 05:36, Damien Miller wrote:> On Sun, 9 Sep 2012, Lars Nordin wrote: > >> Hi, >> >> I needed to convert a public RSA key to autorized_keys format and found >> ssh-keygen lacking this feature. >> >> I made the option -Q publicfile to allow an conversion like >> ssh-keygen -Q pubrsa.pem -y >> >> The patch is produced using unified diff and made on latest release. > I think you can do this already: > > [djm at fuyu ~]$ openssl genrsa 1024 > /tmp/k.key > Generating RSA private key, 1024 bit long modulus > ..........................++++++ > ............................................++++++ > e is 65537 (0x10001) > [djm at fuyu ~]$ openssl rsa -pubout < /tmp/k.key > /tmp/k.pub > writing RSA key > [djm at fuyu ~]$ cat /tmp/k.pub > -----BEGIN PUBLIC KEY----- > MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCU7vN7q9f9bHiAYdxvyyGAwGgS > LmVxczjf8V+YArEIcAuv8hHR4PkvXS4oWBJyUlNbRxr419NLAVcHmo1Pdnnxqan+ > p2HO5n16Syy9eKtJ2/SKYjJlTDh9EdR3Xr2uDYziDcpT30EIhUn9soAX21lILaxo > RFmlsTOOnXFwf9PweQIDAQAB > -----END PUBLIC KEY----- > [djm at fuyu ~]$ ssh-keygen -i -f /tmp/k.pub -m pkcs8 > ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQCU7vN7q9f9bHiAYdxvyyGAwGgSLmVxczjf8V+YArEIcAuv8hHR4PkvXS4oWBJyUlNbRxr419NLAVcHmo1Pdnnxqan+p2HO5n16Syy9eKtJ2/SKYjJlTDh9EdR3Xr2uDYziDcpT30EIhUn9soAX21lILaxoRFmlsTOOnXFwf9PweQ=> > -d > >Damien, My bad, thank you! I wrote the patch for openssh 4.7 with some other changes. In 6.1 I just patched without trying to see if the new options would work (the projekt only needed this changes, so I thought it was easy to send in an patch) Regards /Lars
Reasonably Related Threads
- removing keys from ssh-agent without having key file
- Call for testing: OpenSSH 6.8
- [Bug 2342] New: ssh-keygen gives wrong error loading public key message
- [Bug 2503] New: The sshd log files are insufficient to detect sessions
- [Bug 1550] New: Move from 3DES to AES-256 for private key encryption