version 1.79, 2019/07/07 01:05:00 |
version 1.80, 2019/07/15 13:16:29 |
|
|
|
|
|
|
#ifdef WITH_OPENSSL |
#ifdef WITH_OPENSSL |
/* convert SSH v2 key in OpenSSL PEM format */ |
/* convert SSH v2 key to PEM or PKCS#8 format */ |
static int |
static int |
sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *buf, |
sshkey_private_to_blob_pem_pkcs8(struct sshkey *key, struct sshbuf *buf, |
const char *_passphrase, const char *comment) |
int format, const char *_passphrase, const char *comment) |
{ |
{ |
int was_shielded = sshkey_is_shielded(key); |
int was_shielded = sshkey_is_shielded(key); |
int success, r; |
int success, r; |
|
|
char *bptr; |
char *bptr; |
BIO *bio = NULL; |
BIO *bio = NULL; |
struct sshbuf *blob; |
struct sshbuf *blob; |
|
EVP_PKEY *pkey = NULL; |
|
|
if (len > 0 && len <= 4) |
if (len > 0 && len <= 4) |
return SSH_ERR_PASSPHRASE_TOO_SHORT; |
return SSH_ERR_PASSPHRASE_TOO_SHORT; |
if ((blob = sshbuf_new()) == NULL) |
if ((blob = sshbuf_new()) == NULL) |
return SSH_ERR_ALLOC_FAIL; |
return SSH_ERR_ALLOC_FAIL; |
if ((bio = BIO_new(BIO_s_mem())) == NULL) { |
if ((bio = BIO_new(BIO_s_mem())) == NULL) { |
sshbuf_free(blob); |
r = SSH_ERR_ALLOC_FAIL; |
return 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) |
if ((r = sshkey_unshield_private(key)) != 0) |
goto out; |
goto out; |
|
|
switch (key->type) { |
switch (key->type) { |
case KEY_DSA: |
case KEY_DSA: |
success = PEM_write_bio_DSAPrivateKey(bio, key->dsa, |
if (format == SSHKEY_PRIVATE_PEM) { |
cipher, passphrase, len, NULL, NULL); |
success = PEM_write_bio_DSAPrivateKey(bio, key->dsa, |
|
cipher, passphrase, len, NULL, NULL); |
|
} else { |
|
success = EVP_PKEY_set1_DSA(pkey, key->dsa); |
|
} |
break; |
break; |
case KEY_ECDSA: |
case KEY_ECDSA: |
success = PEM_write_bio_ECPrivateKey(bio, key->ecdsa, |
if (format == SSHKEY_PRIVATE_PEM) { |
cipher, passphrase, len, NULL, NULL); |
success = PEM_write_bio_ECPrivateKey(bio, key->ecdsa, |
|
cipher, passphrase, len, NULL, NULL); |
|
} else { |
|
success = EVP_PKEY_set1_EC_KEY(pkey, key->ecdsa); |
|
} |
break; |
break; |
case KEY_RSA: |
case KEY_RSA: |
success = PEM_write_bio_RSAPrivateKey(bio, key->rsa, |
if (format == SSHKEY_PRIVATE_PEM) { |
cipher, passphrase, len, NULL, NULL); |
success = PEM_write_bio_RSAPrivateKey(bio, key->rsa, |
|
cipher, passphrase, len, NULL, NULL); |
|
} else { |
|
success = EVP_PKEY_set1_RSA(pkey, key->rsa); |
|
} |
break; |
break; |
default: |
default: |
success = 0; |
success = 0; |
|
|
r = SSH_ERR_LIBCRYPTO_ERROR; |
r = SSH_ERR_LIBCRYPTO_ERROR; |
goto out; |
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) { |
if ((blen = BIO_get_mem_data(bio, &bptr)) <= 0) { |
r = SSH_ERR_INTERNAL_ERROR; |
r = SSH_ERR_INTERNAL_ERROR; |
goto out; |
goto out; |
|
|
r = sshkey_shield_private(key); |
r = sshkey_shield_private(key); |
if (r == 0) |
if (r == 0) |
r = sshbuf_putb(buf, blob); |
r = sshbuf_putb(buf, blob); |
sshbuf_free(blob); |
|
|
|
|
EVP_PKEY_free(pkey); |
|
sshbuf_free(blob); |
BIO_free(bio); |
BIO_free(bio); |
return r; |
return r; |
} |
} |
|
|
int |
int |
sshkey_private_to_fileblob(struct sshkey *key, struct sshbuf *blob, |
sshkey_private_to_fileblob(struct sshkey *key, struct sshbuf *blob, |
const char *passphrase, const char *comment, |
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) { |
switch (key->type) { |
#ifdef WITH_OPENSSL |
#ifdef WITH_OPENSSL |
case KEY_DSA: |
case KEY_DSA: |
case KEY_ECDSA: |
case KEY_ECDSA: |
case KEY_RSA: |
case KEY_RSA: |
if (force_new_format) { |
break; /* see below */ |
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); |
|
#endif /* WITH_OPENSSL */ |
#endif /* WITH_OPENSSL */ |
case KEY_ED25519: |
case KEY_ED25519: |
#ifdef WITH_XMSS |
#ifdef WITH_XMSS |
case KEY_XMSS: |
case KEY_XMSS: |
#endif /* WITH_XMSS */ |
#endif /* WITH_XMSS */ |
return sshkey_private_to_blob2(key, blob, passphrase, |
return sshkey_private_to_blob2(key, blob, passphrase, |
comment, new_format_cipher, new_format_rounds); |
comment, openssh_format_cipher, openssh_format_rounds); |
default: |
default: |
return SSH_ERR_KEY_TYPE_UNKNOWN; |
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 */ |
} |
} |
|
|
|
|