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