View | Details | Raw Unified | Return to bug 3013
Collapse All | Expand All

(-)a/authfile.c (-2 / +2 lines)
Lines 74-80 sshkey_save_private_blob(struct sshbuf *keybuf, const char *filename) Link Here
74
int
74
int
75
sshkey_save_private(struct sshkey *key, const char *filename,
75
sshkey_save_private(struct sshkey *key, const char *filename,
76
    const char *passphrase, const char *comment,
76
    const char *passphrase, const char *comment,
77
    int force_new_format, const char *new_format_cipher, int new_format_rounds)
77
    int format, const char *openssh_format_cipher, int openssh_format_rounds)
78
{
78
{
79
	struct sshbuf *keyblob = NULL;
79
	struct sshbuf *keyblob = NULL;
80
	int r;
80
	int r;
Lines 82-88 sshkey_save_private(struct sshkey *key, const char *filename, Link Here
82
	if ((keyblob = sshbuf_new()) == NULL)
82
	if ((keyblob = sshbuf_new()) == NULL)
83
		return SSH_ERR_ALLOC_FAIL;
83
		return SSH_ERR_ALLOC_FAIL;
84
	if ((r = sshkey_private_to_fileblob(key, keyblob, passphrase, comment,
84
	if ((r = sshkey_private_to_fileblob(key, keyblob, passphrase, comment,
85
	    force_new_format, new_format_cipher, new_format_rounds)) != 0)
85
	    format, openssh_format_cipher, openssh_format_rounds)) != 0)
86
		goto out;
86
		goto out;
87
	if ((r = sshkey_save_private_blob(keyblob, filename)) != 0)
87
	if ((r = sshkey_save_private_blob(keyblob, filename)) != 0)
88
		goto out;
88
		goto out;
(-)a/ssh-keygen.1 (-2 / +3 lines)
Lines 419-429 The supported key formats are: Link Here
419
.Dq RFC4716
419
.Dq RFC4716
420
(RFC 4716/SSH2 public or private key),
420
(RFC 4716/SSH2 public or private key),
421
.Dq PKCS8
421
.Dq PKCS8
422
(PEM PKCS8 public key)
422
(PKCS8 public or private key)
423
or
423
or
424
.Dq PEM
424
.Dq PEM
425
(PEM public key).
425
(PEM public key).
426
The default conversion format is
426
By default OpenSSH will write newly-generated private keys in its own
427
format, but when converting public keys for export the default format is
427
.Dq RFC4716 .
428
.Dq RFC4716 .
428
Setting a format of
429
Setting a format of
429
.Dq PEM
430
.Dq PEM
(-)a/ssh-keygen.c (-10 / +13 lines)
Lines 147-157 static char *key_type_name = NULL; Link Here
147
/* Load key from this PKCS#11 provider */
147
/* Load key from this PKCS#11 provider */
148
static char *pkcs11provider = NULL;
148
static char *pkcs11provider = NULL;
149
149
150
/* Use new OpenSSH private key format when writing SSH2 keys instead of PEM */
150
/* Format for writing private keys */
151
static int use_new_format = 1;
151
static int private_key_format = SSHKEY_PRIVATE_OPENSSH;
152
152
153
/* Cipher for new-format private keys */
153
/* Cipher for new-format private keys */
154
static char *new_format_cipher = NULL;
154
static char *openssh_format_cipher = NULL;
155
155
156
/*
156
/*
157
 * Number of KDF rounds to derive new format keys /
157
 * Number of KDF rounds to derive new format keys /
Lines 1048-1054 do_gen_all_hostkeys(struct passwd *pw) Link Here
1048
		snprintf(comment, sizeof comment, "%s@%s", pw->pw_name,
1048
		snprintf(comment, sizeof comment, "%s@%s", pw->pw_name,
1049
		    hostname);
1049
		    hostname);
1050
		if ((r = sshkey_save_private(private, prv_tmp, "",
1050
		if ((r = sshkey_save_private(private, prv_tmp, "",
1051
		    comment, use_new_format, new_format_cipher, rounds)) != 0) {
1051
		    comment, private_key_format, openssh_format_cipher,
1052
		    rounds)) != 0) {
1052
			error("Saving key \"%s\" failed: %s",
1053
			error("Saving key \"%s\" failed: %s",
1053
			    prv_tmp, ssh_err(r));
1054
			    prv_tmp, ssh_err(r));
1054
			goto failnext;
1055
			goto failnext;
Lines 1391-1397 do_change_passphrase(struct passwd *pw) Link Here
1391
1392
1392
	/* Save the file using the new passphrase. */
1393
	/* Save the file using the new passphrase. */
1393
	if ((r = sshkey_save_private(private, identity_file, passphrase1,
1394
	if ((r = sshkey_save_private(private, identity_file, passphrase1,
1394
	    comment, use_new_format, new_format_cipher, rounds)) != 0) {
1395
	    comment, private_key_format, openssh_format_cipher, rounds)) != 0) {
1395
		error("Saving key \"%s\" failed: %s.",
1396
		error("Saving key \"%s\" failed: %s.",
1396
		    identity_file, ssh_err(r));
1397
		    identity_file, ssh_err(r));
1397
		explicit_bzero(passphrase1, strlen(passphrase1));
1398
		explicit_bzero(passphrase1, strlen(passphrase1));
Lines 1480-1486 do_change_comment(struct passwd *pw, const char *identity_comment) Link Here
1480
	}
1481
	}
1481
1482
1482
	if (private->type != KEY_ED25519 && private->type != KEY_XMSS &&
1483
	if (private->type != KEY_ED25519 && private->type != KEY_XMSS &&
1483
	    !use_new_format) {
1484
	    private_key_format != SSHKEY_PRIVATE_OPENSSH) {
1484
		error("Comments are only supported for keys stored in "
1485
		error("Comments are only supported for keys stored in "
1485
		    "the new format (-o).");
1486
		    "the new format (-o).");
1486
		explicit_bzero(passphrase, strlen(passphrase));
1487
		explicit_bzero(passphrase, strlen(passphrase));
Lines 1514-1520 do_change_comment(struct passwd *pw, const char *identity_comment) Link Here
1514
1515
1515
	/* Save the file using the new passphrase. */
1516
	/* Save the file using the new passphrase. */
1516
	if ((r = sshkey_save_private(private, identity_file, passphrase,
1517
	if ((r = sshkey_save_private(private, identity_file, passphrase,
1517
	    new_comment, use_new_format, new_format_cipher, rounds)) != 0) {
1518
	    new_comment, private_key_format, openssh_format_cipher,
1519
	    rounds)) != 0) {
1518
		error("Saving key \"%s\" failed: %s",
1520
		error("Saving key \"%s\" failed: %s",
1519
		    identity_file, ssh_err(r));
1521
		    identity_file, ssh_err(r));
1520
		explicit_bzero(passphrase, strlen(passphrase));
1522
		explicit_bzero(passphrase, strlen(passphrase));
Lines 2525-2535 main(int argc, char **argv) Link Here
2525
			}
2527
			}
2526
			if (strcasecmp(optarg, "PKCS8") == 0) {
2528
			if (strcasecmp(optarg, "PKCS8") == 0) {
2527
				convert_format = FMT_PKCS8;
2529
				convert_format = FMT_PKCS8;
2530
				private_key_format = SSHKEY_PRIVATE_PKCS8;
2528
				break;
2531
				break;
2529
			}
2532
			}
2530
			if (strcasecmp(optarg, "PEM") == 0) {
2533
			if (strcasecmp(optarg, "PEM") == 0) {
2531
				convert_format = FMT_PEM;
2534
				convert_format = FMT_PEM;
2532
				use_new_format = 0;
2535
				private_key_format = SSHKEY_PRIVATE_PEM;
2533
				break;
2536
				break;
2534
			}
2537
			}
2535
			fatal("Unsupported conversion format \"%s\"", optarg);
2538
			fatal("Unsupported conversion format \"%s\"", optarg);
Lines 2567-2573 main(int argc, char **argv) Link Here
2567
			add_cert_option(optarg);
2570
			add_cert_option(optarg);
2568
			break;
2571
			break;
2569
		case 'Z':
2572
		case 'Z':
2570
			new_format_cipher = optarg;
2573
			openssh_format_cipher = optarg;
2571
			break;
2574
			break;
2572
		case 'C':
2575
		case 'C':
2573
			identity_comment = optarg;
2576
			identity_comment = optarg;
Lines 2912-2918 passphrase_again: Link Here
2912
2915
2913
	/* Save the key with the given passphrase and comment. */
2916
	/* Save the key with the given passphrase and comment. */
2914
	if ((r = sshkey_save_private(private, identity_file, passphrase1,
2917
	if ((r = sshkey_save_private(private, identity_file, passphrase1,
2915
	    comment, use_new_format, new_format_cipher, rounds)) != 0) {
2918
	    comment, private_key_format, openssh_format_cipher, rounds)) != 0) {
2916
		error("Saving key \"%s\" failed: %s",
2919
		error("Saving key \"%s\" failed: %s",
2917
		    identity_file, ssh_err(r));
2920
		    identity_file, ssh_err(r));
2918
		explicit_bzero(passphrase1, strlen(passphrase1));
2921
		explicit_bzero(passphrase1, strlen(passphrase1));
(-)a/sshkey.c (-20 / +54 lines)
Lines 3977-3986 sshkey_parse_private2(struct sshbuf *blob, int type, const char *passphrase, Link Here
3977
3977
3978
3978
3979
#ifdef WITH_OPENSSL
3979
#ifdef WITH_OPENSSL
3980
/* convert SSH v2 key in OpenSSL PEM format */
3980
/* convert SSH v2 key to PEM or PKCS#8 format */
3981
static int
3981
static int
3982
sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *buf,
3982
sshkey_private_to_blob_pem_pkcs8(struct sshkey *key, struct sshbuf *buf,
3983
    const char *_passphrase, const char *comment)
3983
    int format, const char *_passphrase, const char *comment)
3984
{
3984
{
3985
	int was_shielded = sshkey_is_shielded(key);
3985
	int was_shielded = sshkey_is_shielded(key);
3986
	int success, r;
3986
	int success, r;
Lines 3990-4021 sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *buf, Link Here
3990
	char *bptr;
3990
	char *bptr;
3991
	BIO *bio = NULL;
3991
	BIO *bio = NULL;
3992
	struct sshbuf *blob;
3992
	struct sshbuf *blob;
3993
	EVP_PKEY *pkey = NULL;
3993
3994
3994
	if (len > 0 && len <= 4)
3995
	if (len > 0 && len <= 4)
3995
		return SSH_ERR_PASSPHRASE_TOO_SHORT;
3996
		return SSH_ERR_PASSPHRASE_TOO_SHORT;
3996
	if ((blob = sshbuf_new()) == NULL)
3997
	if ((blob = sshbuf_new()) == NULL)
3997
		return SSH_ERR_ALLOC_FAIL;
3998
		return SSH_ERR_ALLOC_FAIL;
3998
	if ((bio = BIO_new(BIO_s_mem())) == NULL) {
3999
	if ((bio = BIO_new(BIO_s_mem())) == NULL) {
3999
		sshbuf_free(blob);
4000
		r = SSH_ERR_ALLOC_FAIL;
4000
		return SSH_ERR_ALLOC_FAIL;
4001
		goto out;
4002
	}
4003
	if (format == SSHKEY_PRIVATE_PKCS8 && (pkey = EVP_PKEY_new()) == NULL) {
4004
		r = SSH_ERR_ALLOC_FAIL;
4005
		goto out;
4001
	}
4006
	}
4002
	if ((r = sshkey_unshield_private(key)) != 0)
4007
	if ((r = sshkey_unshield_private(key)) != 0)
4003
		goto out;
4008
		goto out;
4004
4009
4005
	switch (key->type) {
4010
	switch (key->type) {
4006
	case KEY_DSA:
4011
	case KEY_DSA:
4007
		success = PEM_write_bio_DSAPrivateKey(bio, key->dsa,
4012
		if (format == SSHKEY_PRIVATE_PEM) {
4008
		    cipher, passphrase, len, NULL, NULL);
4013
			success = PEM_write_bio_DSAPrivateKey(bio, key->dsa,
4014
			    cipher, passphrase, len, NULL, NULL);
4015
		} else {
4016
			success = EVP_PKEY_set1_DSA(pkey, key->dsa);
4017
		}
4009
		break;
4018
		break;
4010
#ifdef OPENSSL_HAS_ECC
4019
#ifdef OPENSSL_HAS_ECC
4011
	case KEY_ECDSA:
4020
	case KEY_ECDSA:
4012
		success = PEM_write_bio_ECPrivateKey(bio, key->ecdsa,
4021
		if (format == SSHKEY_PRIVATE_PEM) {
4013
		    cipher, passphrase, len, NULL, NULL);
4022
			success = PEM_write_bio_ECPrivateKey(bio, key->ecdsa,
4023
			    cipher, passphrase, len, NULL, NULL);
4024
		} else {
4025
			success = EVP_PKEY_set1_EC_KEY(pkey, key->ecdsa);
4026
		}
4014
		break;
4027
		break;
4015
#endif
4028
#endif
4016
	case KEY_RSA:
4029
	case KEY_RSA:
4017
		success = PEM_write_bio_RSAPrivateKey(bio, key->rsa,
4030
		if (format == SSHKEY_PRIVATE_PEM) {
4018
		    cipher, passphrase, len, NULL, NULL);
4031
			success = PEM_write_bio_RSAPrivateKey(bio, key->rsa,
4032
			    cipher, passphrase, len, NULL, NULL);
4033
		} else {
4034
			success = EVP_PKEY_set1_RSA(pkey, key->rsa);
4035
		}
4019
		break;
4036
		break;
4020
	default:
4037
	default:
4021
		success = 0;
4038
		success = 0;
Lines 4025-4030 sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *buf, Link Here
4025
		r = SSH_ERR_LIBCRYPTO_ERROR;
4042
		r = SSH_ERR_LIBCRYPTO_ERROR;
4026
		goto out;
4043
		goto out;
4027
	}
4044
	}
4045
	if (format == SSHKEY_PRIVATE_PKCS8) {
4046
		if ((success = PEM_write_bio_PrivateKey(bio, pkey, cipher,
4047
		    passphrase, len, NULL, NULL)) == 0) {
4048
			r = SSH_ERR_LIBCRYPTO_ERROR;
4049
			goto out;
4050
		}
4051
	}
4028
	if ((blen = BIO_get_mem_data(bio, &bptr)) <= 0) {
4052
	if ((blen = BIO_get_mem_data(bio, &bptr)) <= 0) {
4029
		r = SSH_ERR_INTERNAL_ERROR;
4053
		r = SSH_ERR_INTERNAL_ERROR;
4030
		goto out;
4054
		goto out;
Lines 4037-4044 sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *buf, Link Here
4037
		r = sshkey_shield_private(key);
4061
		r = sshkey_shield_private(key);
4038
	if (r == 0)
4062
	if (r == 0)
4039
		r = sshbuf_putb(buf, blob);
4063
		r = sshbuf_putb(buf, blob);
4040
	sshbuf_free(blob);
4041
4064
4065
	EVP_PKEY_free(pkey);
4066
	sshbuf_free(blob);
4042
	BIO_free(bio);
4067
	BIO_free(bio);
4043
	return r;
4068
	return r;
4044
}
4069
}
Lines 4048-4076 sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *buf, Link Here
4048
int
4073
int
4049
sshkey_private_to_fileblob(struct sshkey *key, struct sshbuf *blob,
4074
sshkey_private_to_fileblob(struct sshkey *key, struct sshbuf *blob,
4050
    const char *passphrase, const char *comment,
4075
    const char *passphrase, const char *comment,
4051
    int force_new_format, const char *new_format_cipher, int new_format_rounds)
4076
    int format, const char *openssh_format_cipher, int openssh_format_rounds)
4052
{
4077
{
4053
	switch (key->type) {
4078
	switch (key->type) {
4054
#ifdef WITH_OPENSSL
4079
#ifdef WITH_OPENSSL
4055
	case KEY_DSA:
4080
	case KEY_DSA:
4056
	case KEY_ECDSA:
4081
	case KEY_ECDSA:
4057
	case KEY_RSA:
4082
	case KEY_RSA:
4058
		if (force_new_format) {
4083
		break; /* see below */
4059
			return sshkey_private_to_blob2(key, blob, passphrase,
4060
			    comment, new_format_cipher, new_format_rounds);
4061
		}
4062
		return sshkey_private_pem_to_blob(key, blob,
4063
		    passphrase, comment);
4064
#endif /* WITH_OPENSSL */
4084
#endif /* WITH_OPENSSL */
4065
	case KEY_ED25519:
4085
	case KEY_ED25519:
4066
#ifdef WITH_XMSS
4086
#ifdef WITH_XMSS
4067
	case KEY_XMSS:
4087
	case KEY_XMSS:
4068
#endif /* WITH_XMSS */
4088
#endif /* WITH_XMSS */
4069
		return sshkey_private_to_blob2(key, blob, passphrase,
4089
		return sshkey_private_to_blob2(key, blob, passphrase,
4070
		    comment, new_format_cipher, new_format_rounds);
4090
		    comment, openssh_format_cipher, openssh_format_rounds);
4071
	default:
4091
	default:
4072
		return SSH_ERR_KEY_TYPE_UNKNOWN;
4092
		return SSH_ERR_KEY_TYPE_UNKNOWN;
4073
	}
4093
	}
4094
4095
#ifdef WITH_OPENSSL
4096
	switch (format) {
4097
	case SSHKEY_PRIVATE_OPENSSH:
4098
		return sshkey_private_to_blob2(key, blob, passphrase,
4099
		    comment, openssh_format_cipher, openssh_format_rounds);
4100
	case SSHKEY_PRIVATE_PEM:
4101
	case SSHKEY_PRIVATE_PKCS8:
4102
		return sshkey_private_to_blob_pem_pkcs8(key, blob,
4103
		    format, passphrase, comment);
4104
	default:
4105
		return SSH_ERR_INVALID_ARGUMENT;
4106
	}
4107
#endif /* WITH_OPENSSL */
4074
}
4108
}
4075
4109
4076
4110
(-)a/sshkey.h (-1 / +8 lines)
Lines 88-93 enum sshkey_serialize_rep { Link Here
88
	SSHKEY_SERIALIZE_INFO = 254,
88
	SSHKEY_SERIALIZE_INFO = 254,
89
};
89
};
90
90
91
/* Private key disk formats */
92
enum sshkey_private_format {
93
	SSHKEY_PRIVATE_OPENSSH = 0,
94
	SSHKEY_PRIVATE_PEM = 1,
95
	SSHKEY_PRIVATE_PKCS8 = 2,
96
};
97
91
/* key is stored in external hardware */
98
/* key is stored in external hardware */
92
#define SSHKEY_FLAG_EXT		0x0001
99
#define SSHKEY_FLAG_EXT		0x0001
93
100
Lines 221-227 int sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **keyp); Link Here
221
/* private key file format parsing and serialisation */
228
/* private key file format parsing and serialisation */
222
int	sshkey_private_to_fileblob(struct sshkey *key, struct sshbuf *blob,
229
int	sshkey_private_to_fileblob(struct sshkey *key, struct sshbuf *blob,
223
    const char *passphrase, const char *comment,
230
    const char *passphrase, const char *comment,
224
    int force_new_format, const char *new_format_cipher, int new_format_rounds);
231
    int format, const char *openssh_format_cipher, int openssh_format_rounds);
225
int	sshkey_parse_private_fileblob(struct sshbuf *buffer,
232
int	sshkey_parse_private_fileblob(struct sshbuf *buffer,
226
    const char *passphrase, struct sshkey **keyp, char **commentp);
233
    const char *passphrase, struct sshkey **keyp, char **commentp);
227
int	sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type,
234
int	sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type,

Return to bug 3013