Bugzilla – Attachment 3295 Details for
Bug 3013
Use the PKCS#8 formatted PEM files instead of insecure "traditional PEM"
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
support pkcs#8 and PEM
pkcs8.diff (text/plain), 10.35 KB, created by
Damien Miller
on 2019-07-05 15:21:53 AEST
(
hide
)
Description:
support pkcs#8 and PEM
Filename:
MIME Type:
Creator:
Damien Miller
Created:
2019-07-05 15:21:53 AEST
Size:
10.35 KB
patch
obsolete
>diff --git a/authfile.c b/authfile.c >index 2166c168..19377dcf 100644 >--- a/authfile.c >+++ b/authfile.c >@@ -74,7 +74,7 @@ sshkey_save_private_blob(struct sshbuf *keybuf, const char *filename) > int > sshkey_save_private(struct sshkey *key, const char *filename, > const char *passphrase, const char *comment, >- int force_new_format, const char *new_format_cipher, int new_format_rounds) >+ int format, const char *openssh_format_cipher, int openssh_format_rounds) > { > struct sshbuf *keyblob = NULL; > int r; >@@ -82,7 +82,7 @@ sshkey_save_private(struct sshkey *key, const char *filename, > if ((keyblob = sshbuf_new()) == NULL) > return SSH_ERR_ALLOC_FAIL; > if ((r = sshkey_private_to_fileblob(key, keyblob, passphrase, comment, >- force_new_format, new_format_cipher, new_format_rounds)) != 0) >+ format, openssh_format_cipher, openssh_format_rounds)) != 0) > goto out; > if ((r = sshkey_save_private_blob(keyblob, filename)) != 0) > goto out; >diff --git a/ssh-keygen.1 b/ssh-keygen.1 >index f42127c6..27e93269 100644 >--- a/ssh-keygen.1 >+++ b/ssh-keygen.1 >@@ -419,11 +419,12 @@ The supported key formats are: > .Dq RFC4716 > (RFC 4716/SSH2 public or private key), > .Dq PKCS8 >-(PEM PKCS8 public key) >+(PKCS8 public or private key) > or > .Dq PEM > (PEM public key). >-The default conversion format is >+By default OpenSSH will write newly-generated private keys in its own >+format, but when converting public keys for export the default format is > .Dq RFC4716 . > Setting a format of > .Dq PEM >diff --git a/ssh-keygen.c b/ssh-keygen.c >index 3aa4f512..f196ebb3 100644 >--- a/ssh-keygen.c >+++ b/ssh-keygen.c >@@ -147,11 +147,11 @@ static char *key_type_name = NULL; > /* Load key from this PKCS#11 provider */ > static char *pkcs11provider = NULL; > >-/* Use new OpenSSH private key format when writing SSH2 keys instead of PEM */ >-static int use_new_format = 1; >+/* Format for writing private keys */ >+static int private_key_format = SSHKEY_PRIVATE_OPENSSH; > > /* Cipher for new-format private keys */ >-static char *new_format_cipher = NULL; >+static char *openssh_format_cipher = NULL; > > /* > * Number of KDF rounds to derive new format keys / >@@ -1048,7 +1048,8 @@ do_gen_all_hostkeys(struct passwd *pw) > snprintf(comment, sizeof comment, "%s@%s", pw->pw_name, > hostname); > if ((r = sshkey_save_private(private, prv_tmp, "", >- comment, use_new_format, new_format_cipher, rounds)) != 0) { >+ comment, private_key_format, openssh_format_cipher, >+ rounds)) != 0) { > error("Saving key \"%s\" failed: %s", > prv_tmp, ssh_err(r)); > goto failnext; >@@ -1391,7 +1392,7 @@ do_change_passphrase(struct passwd *pw) > > /* Save the file using the new passphrase. */ > if ((r = sshkey_save_private(private, identity_file, passphrase1, >- comment, use_new_format, new_format_cipher, rounds)) != 0) { >+ comment, private_key_format, openssh_format_cipher, rounds)) != 0) { > error("Saving key \"%s\" failed: %s.", > identity_file, ssh_err(r)); > explicit_bzero(passphrase1, strlen(passphrase1)); >@@ -1480,7 +1481,7 @@ do_change_comment(struct passwd *pw, const char *identity_comment) > } > > if (private->type != KEY_ED25519 && private->type != KEY_XMSS && >- !use_new_format) { >+ private_key_format != SSHKEY_PRIVATE_OPENSSH) { > error("Comments are only supported for keys stored in " > "the new format (-o)."); > explicit_bzero(passphrase, strlen(passphrase)); >@@ -1514,7 +1515,8 @@ do_change_comment(struct passwd *pw, const char *identity_comment) > > /* Save the file using the new passphrase. */ > if ((r = sshkey_save_private(private, identity_file, passphrase, >- new_comment, use_new_format, new_format_cipher, rounds)) != 0) { >+ new_comment, private_key_format, openssh_format_cipher, >+ rounds)) != 0) { > error("Saving key \"%s\" failed: %s", > identity_file, ssh_err(r)); > explicit_bzero(passphrase, strlen(passphrase)); >@@ -2525,11 +2527,12 @@ main(int argc, char **argv) > } > if (strcasecmp(optarg, "PKCS8") == 0) { > convert_format = FMT_PKCS8; >+ private_key_format = SSHKEY_PRIVATE_PKCS8; > break; > } > if (strcasecmp(optarg, "PEM") == 0) { > convert_format = FMT_PEM; >- use_new_format = 0; >+ private_key_format = SSHKEY_PRIVATE_PEM; > break; > } > fatal("Unsupported conversion format \"%s\"", optarg); >@@ -2567,7 +2570,7 @@ main(int argc, char **argv) > add_cert_option(optarg); > break; > case 'Z': >- new_format_cipher = optarg; >+ openssh_format_cipher = optarg; > break; > case 'C': > identity_comment = optarg; >@@ -2912,7 +2915,7 @@ passphrase_again: > > /* Save the key with the given passphrase and comment. */ > if ((r = sshkey_save_private(private, identity_file, passphrase1, >- comment, use_new_format, new_format_cipher, rounds)) != 0) { >+ comment, private_key_format, openssh_format_cipher, rounds)) != 0) { > error("Saving key \"%s\" failed: %s", > identity_file, ssh_err(r)); > explicit_bzero(passphrase1, strlen(passphrase1)); >diff --git a/sshkey.c b/sshkey.c >index 5d28c457..c39cefaa 100644 >--- a/sshkey.c >+++ b/sshkey.c >@@ -3977,10 +3977,10 @@ sshkey_parse_private2(struct sshbuf *blob, int type, const char *passphrase, > > > #ifdef WITH_OPENSSL >-/* convert SSH v2 key in OpenSSL PEM format */ >+/* convert SSH v2 key to PEM or PKCS#8 format */ > static int >-sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *buf, >- const char *_passphrase, const char *comment) >+sshkey_private_to_blob_pem_pkcs8(struct sshkey *key, struct sshbuf *buf, >+ int format, const char *_passphrase, const char *comment) > { > int was_shielded = sshkey_is_shielded(key); > int success, r; >@@ -3990,32 +3990,49 @@ sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *buf, > char *bptr; > BIO *bio = NULL; > struct sshbuf *blob; >+ EVP_PKEY *pkey = NULL; > > if (len > 0 && len <= 4) > return SSH_ERR_PASSPHRASE_TOO_SHORT; > if ((blob = sshbuf_new()) == NULL) > return SSH_ERR_ALLOC_FAIL; > if ((bio = BIO_new(BIO_s_mem())) == NULL) { >- sshbuf_free(blob); >- return SSH_ERR_ALLOC_FAIL; >+ r = SSH_ERR_ALLOC_FAIL; >+ goto out; >+ } >+ if (format == SSHKEY_PRIVATE_PKCS8 && (pkey = EVP_PKEY_new()) == NULL) { >+ r = SSH_ERR_ALLOC_FAIL; >+ goto out; > } > if ((r = sshkey_unshield_private(key)) != 0) > goto out; > > switch (key->type) { > case KEY_DSA: >- success = PEM_write_bio_DSAPrivateKey(bio, key->dsa, >- cipher, passphrase, len, NULL, NULL); >+ if (format == SSHKEY_PRIVATE_PEM) { >+ success = PEM_write_bio_DSAPrivateKey(bio, key->dsa, >+ cipher, passphrase, len, NULL, NULL); >+ } else { >+ success = EVP_PKEY_set1_DSA(pkey, key->dsa); >+ } > break; > #ifdef OPENSSL_HAS_ECC > case KEY_ECDSA: >- success = PEM_write_bio_ECPrivateKey(bio, key->ecdsa, >- cipher, passphrase, len, NULL, NULL); >+ if (format == SSHKEY_PRIVATE_PEM) { >+ success = PEM_write_bio_ECPrivateKey(bio, key->ecdsa, >+ cipher, passphrase, len, NULL, NULL); >+ } else { >+ success = EVP_PKEY_set1_EC_KEY(pkey, key->ecdsa); >+ } > break; > #endif > case KEY_RSA: >- success = PEM_write_bio_RSAPrivateKey(bio, key->rsa, >- cipher, passphrase, len, NULL, NULL); >+ if (format == SSHKEY_PRIVATE_PEM) { >+ success = PEM_write_bio_RSAPrivateKey(bio, key->rsa, >+ cipher, passphrase, len, NULL, NULL); >+ } else { >+ success = EVP_PKEY_set1_RSA(pkey, key->rsa); >+ } > break; > default: > success = 0; >@@ -4025,6 +4042,13 @@ sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *buf, > r = SSH_ERR_LIBCRYPTO_ERROR; > goto out; > } >+ if (format == SSHKEY_PRIVATE_PKCS8) { >+ if ((success = PEM_write_bio_PrivateKey(bio, pkey, cipher, >+ passphrase, len, NULL, NULL)) == 0) { >+ r = SSH_ERR_LIBCRYPTO_ERROR; >+ goto out; >+ } >+ } > if ((blen = BIO_get_mem_data(bio, &bptr)) <= 0) { > r = SSH_ERR_INTERNAL_ERROR; > goto out; >@@ -4037,8 +4061,9 @@ sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *buf, > r = sshkey_shield_private(key); > if (r == 0) > r = sshbuf_putb(buf, blob); >- sshbuf_free(blob); > >+ EVP_PKEY_free(pkey); >+ sshbuf_free(blob); > BIO_free(bio); > return r; > } >@@ -4048,29 +4073,38 @@ sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *buf, > int > sshkey_private_to_fileblob(struct sshkey *key, struct sshbuf *blob, > const char *passphrase, const char *comment, >- int force_new_format, const char *new_format_cipher, int new_format_rounds) >+ int format, const char *openssh_format_cipher, int openssh_format_rounds) > { > switch (key->type) { > #ifdef WITH_OPENSSL > case KEY_DSA: > case KEY_ECDSA: > case KEY_RSA: >- if (force_new_format) { >- return sshkey_private_to_blob2(key, blob, passphrase, >- comment, new_format_cipher, new_format_rounds); >- } >- return sshkey_private_pem_to_blob(key, blob, >- passphrase, comment); >+ break; /* see below */ > #endif /* WITH_OPENSSL */ > case KEY_ED25519: > #ifdef WITH_XMSS > case KEY_XMSS: > #endif /* WITH_XMSS */ > return sshkey_private_to_blob2(key, blob, passphrase, >- comment, new_format_cipher, new_format_rounds); >+ comment, openssh_format_cipher, openssh_format_rounds); > default: > return SSH_ERR_KEY_TYPE_UNKNOWN; > } >+ >+#ifdef WITH_OPENSSL >+ switch (format) { >+ case SSHKEY_PRIVATE_OPENSSH: >+ return sshkey_private_to_blob2(key, blob, passphrase, >+ comment, openssh_format_cipher, openssh_format_rounds); >+ case SSHKEY_PRIVATE_PEM: >+ case SSHKEY_PRIVATE_PKCS8: >+ return sshkey_private_to_blob_pem_pkcs8(key, blob, >+ format, passphrase, comment); >+ default: >+ return SSH_ERR_INVALID_ARGUMENT; >+ } >+#endif /* WITH_OPENSSL */ > } > > >diff --git a/sshkey.h b/sshkey.h >index 41d159a1..14473dc1 100644 >--- a/sshkey.h >+++ b/sshkey.h >@@ -88,6 +88,13 @@ enum sshkey_serialize_rep { > SSHKEY_SERIALIZE_INFO = 254, > }; > >+/* Private key disk formats */ >+enum sshkey_private_format { >+ SSHKEY_PRIVATE_OPENSSH = 0, >+ SSHKEY_PRIVATE_PEM = 1, >+ SSHKEY_PRIVATE_PKCS8 = 2, >+}; >+ > /* key is stored in external hardware */ > #define SSHKEY_FLAG_EXT 0x0001 > >@@ -221,7 +228,7 @@ int sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **keyp); > /* private key file format parsing and serialisation */ > int sshkey_private_to_fileblob(struct sshkey *key, struct sshbuf *blob, > const char *passphrase, const char *comment, >- int force_new_format, const char *new_format_cipher, int new_format_rounds); >+ int format, const char *openssh_format_cipher, int openssh_format_rounds); > int sshkey_parse_private_fileblob(struct sshbuf *buffer, > const char *passphrase, struct sshkey **keyp, char **commentp); > int sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type,
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 3013
:
3286
| 3295