Alon Bar-Lev
2012-Jul-28 18:23 UTC
[PATCH] ssh-keygen: support public key import/export using SubjectPublicKeyInfo
ssh-keygen already supports importing and exporting ssh keys using various formats. The "-m PEM" which should have been the easiest to be used with various of external application expects PKCS#1 encoded key, while many applications use SubjectPublicKeyInfo encoded key. This change adds SubjectPublicKeyInfo support, to ease integration with applications. Examples: ## convert SubjectPublicKeyInfo public key to SSH public key $ openssl req -newkey rsa:2048 -nodes -pubkey -subj "/CN=test" \ -noout -keyout /dev/null | \ ssh-keygen -i -m SUBJECTINFO -f /proc/self/fd/0 ## convert X.509 certificate to SSH public key $ openssl req -newkey rsa:2048 -nodes -x509 -subj "/CN=test" \ -keyout /dev/null | openssl x509 -pubkey -noout | \ ssh-keygen -i -m SUBJECTINFO -f /proc/self/fd/0 ## convert SSH public key to SubjectPublicKeyInfo public key $ ssh-keygen -e -m SUBJECTINFO -f ~/.ssh/id_rsa.pub | \ openssl rsa -pubin -text Signed-off-by: Alon Bar-Lev <alon.barlev at gmail.com> --- ssh-keygen.1 | 6 +++- ssh-keygen.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 69 insertions(+), 3 deletions(-) diff --git a/ssh-keygen.1 b/ssh-keygen.1 index 41da207..88451ac 100644 --- a/ssh-keygen.1 +++ b/ssh-keygen.1 @@ -334,9 +334,11 @@ The supported key formats are: (RFC 4716/SSH2 public or private key), .Dq PKCS8 (PEM PKCS8 public key) -or .Dq PEM -(PEM public key). +(PEM public key) +or +.Dq SUBJECTINFO +(SubjectPublicKeyInfo public key). The default conversion format is .Dq RFC4716 . .It Fl N Ar new_passphrase diff --git a/ssh-keygen.c b/ssh-keygen.c index 5fcd3a1..072c49a 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c @@ -137,7 +137,8 @@ int convert_from = 0; enum { FMT_RFC4716, FMT_PKCS8, - FMT_PEM + FMT_PEM, + FMT_SUBJECTINFO } convert_format = FMT_RFC4716; int print_public = 0; int print_generic = 0; @@ -330,6 +331,27 @@ do_convert_to_pem(Key *k) } static void +do_convert_to_subjectinfo(Key *k) +{ + switch (key_type_plain(k->type)) { + case KEY_RSA: + if (!PEM_write_RSA_PUBKEY(stdout, k->rsa)) + fatal("PEM_write_RSAPublicKey failed"); + break; +#if notyet /* OpenSSH 0.9.8 lacks this function */ + case KEY_DSA: + if (!PEM_write_DSA_PUBKEY(stdout, k->dsa)) + fatal("PEM_write_DSAPublicKey failed"); + break; +#endif + /* XXX ECDSA? */ + default: + fatal("%s: unsupported key type %s", __func__, key_type(k)); + } + exit(0); +} + +static void do_convert_to(struct passwd *pw) { Key *k; @@ -360,6 +382,9 @@ do_convert_to(struct passwd *pw) case FMT_PEM: do_convert_to_pem(k); break; + case FMT_SUBJECTINFO: + do_convert_to_subjectinfo(k); + break; default: fatal("%s: unknown key format %d", __func__, convert_format); } @@ -631,6 +656,38 @@ do_convert_from_pem(Key **k, int *private) } static void +do_convert_from_subjectinfo(Key **k, int *private) +{ + FILE *fp; + RSA *rsa; +#ifdef notyet + DSA *dsa; +#endif + + if ((fp = fopen(identity_file, "r")) == NULL) + fatal("%s: %s: %s", __progname, identity_file, strerror(errno)); + if ((rsa = PEM_read_RSA_PUBKEY(fp, NULL, NULL, NULL)) != NULL) { + *k = key_new(KEY_UNSPEC); + (*k)->type = KEY_RSA; + (*k)->rsa = rsa; + fclose(fp); + return; + } +#if notyet /* OpenSSH 0.9.8 lacks this function */ + rewind(fp); + if ((dsa = PEM_read_DSA_PUBKEY(fp, NULL, NULL, NULL)) != NULL) { + *k = key_new(KEY_UNSPEC); + (*k)->type = KEY_DSA; + (*k)->dsa = dsa; + fclose(fp); + return; + } + /* XXX ECDSA */ +#endif + fatal("%s: unrecognised subjectinfo public key format", __func__); +} + +static void do_convert_from(struct passwd *pw) { Key *k = NULL; @@ -652,6 +709,9 @@ do_convert_from(struct passwd *pw) case FMT_PEM: do_convert_from_pem(&k, &private); break; + case FMT_SUBJECTINFO: + do_convert_from_subjectinfo(&k, &private); + break; default: fatal("%s: unknown key format %d", __func__, convert_format); } @@ -2005,6 +2065,10 @@ main(int argc, char **argv) convert_format = FMT_PEM; break; } + if (strcasecmp(optarg, "SUBJECTINFO") == 0) { + convert_format = FMT_SUBJECTINFO; + break; + } fatal("Unsupported conversion format \"%s\"", optarg); case 'n': cert_principals = optarg; -- 1.7.8.6
Damien Miller
2012-Jul-30 00:24 UTC
[PATCH] ssh-keygen: support public key import/export using SubjectPublicKeyInfo
On Sat, 28 Jul 2012, Alon Bar-Lev wrote:> ssh-keygen already supports importing and exporting ssh keys using > various formats. > > The "-m PEM" which should have been the easiest to be used with > various of external application expects PKCS#1 encoded key, while > many applications use SubjectPublicKeyInfo encoded key. > > This change adds SubjectPublicKeyInfo support, to ease integration > with applications.I've not heard the term "SubjectPublicKeyInfo" used to refer to a public key format before, but what the format you seem to be importing and exporting seems to be what we implement as PKCS8, though I think this might be a misnomer. If you s/SUBJECTINFO/PKCS8/ in your examples then they should work.> Examples: > ## convert SubjectPublicKeyInfo public key to SSH public key > $ openssl req -newkey rsa:2048 -nodes -pubkey -subj "/CN=test" \ > -noout -keyout /dev/null | \ > ssh-keygen -i -m SUBJECTINFO -f /proc/self/fd/0 > > ## convert X.509 certificate to SSH public key > $ openssl req -newkey rsa:2048 -nodes -x509 -subj "/CN=test" \ > -keyout /dev/null | openssl x509 -pubkey -noout | \ > ssh-keygen -i -m SUBJECTINFO -f /proc/self/fd/0 > > ## convert SSH public key to SubjectPublicKeyInfo public key > $ ssh-keygen -e -m SUBJECTINFO -f ~/.ssh/id_rsa.pub | \ > openssl rsa -pubin -text-d
Apparently Analagous Threads
- public key format
- [Bug 2567] New: Wrong terminology used for ssh-keygen "-m" option
- Wishlist: add a variable %{x509} expanding to the client cert in Dovecot-auth
- Patch for ssh-keygen to allow conversion of public key to openssh format
- [PATCH 1/3] Add private key protection information extraction to ssh-keygen