summaryrefslogtreecommitdiffstats
path: root/crypto/openssh/sshkey.c
diff options
context:
space:
mode:
authordes <des@FreeBSD.org>2017-09-02 23:39:51 +0000
committerdes <des@FreeBSD.org>2017-09-02 23:39:51 +0000
commit7e3dcea1a1c17915cbd33fd8fcec2b5530f8d3d1 (patch)
tree0ad6b552b5cee69d3a46a71e4f906a8b18024b1d /crypto/openssh/sshkey.c
parentca26403304720e30901aa6f7bde4883af9662d2d (diff)
downloadFreeBSD-src-7e3dcea1a1c17915cbd33fd8fcec2b5530f8d3d1.zip
FreeBSD-src-7e3dcea1a1c17915cbd33fd8fcec2b5530f8d3d1.tar.gz
MFH (r322052): Upgrade OpenSSH to 7.5p1.
Diffstat (limited to 'crypto/openssh/sshkey.c')
-rw-r--r--crypto/openssh/sshkey.c64
1 files changed, 57 insertions, 7 deletions
diff --git a/crypto/openssh/sshkey.c b/crypto/openssh/sshkey.c
index c01da6c..53a7674 100644
--- a/crypto/openssh/sshkey.c
+++ b/crypto/openssh/sshkey.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshkey.c,v 1.41 2016/10/24 01:09:17 dtucker Exp $ */
+/* $OpenBSD: sshkey.c,v 1.45 2017/03/10 04:07:20 djm Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
* Copyright (c) 2008 Alexander von Gernler. All rights reserved.
@@ -89,7 +89,9 @@ static const struct keytype keytypes[] = {
{ "ssh-ed25519-cert-v01@openssh.com", "ED25519-CERT",
KEY_ED25519_CERT, 0, 1, 0 },
#ifdef WITH_OPENSSL
+# ifdef WITH_SSH1
{ NULL, "RSA1", KEY_RSA1, 0, 0, 0 },
+# endif
{ "ssh-rsa", "RSA", KEY_RSA, 0, 0, 0 },
{ "rsa-sha2-256", "RSA", KEY_RSA, 0, 0, 1 },
{ "rsa-sha2-512", "RSA", KEY_RSA, 0, 0, 1 },
@@ -195,14 +197,16 @@ sshkey_ecdsa_nid_from_name(const char *name)
}
char *
-sshkey_alg_list(int certs_only, int plain_only, char sep)
+sshkey_alg_list(int certs_only, int plain_only, int include_sigonly, char sep)
{
char *tmp, *ret = NULL;
size_t nlen, rlen = 0;
const struct keytype *kt;
for (kt = keytypes; kt->type != -1; kt++) {
- if (kt->name == NULL || kt->sigonly)
+ if (kt->name == NULL)
+ continue;
+ if (!include_sigonly && kt->sigonly)
continue;
if ((certs_only && !kt->cert) || (plain_only && kt->cert))
continue;
@@ -1237,6 +1241,9 @@ sshkey_read(struct sshkey *ret, char **cpp)
u_long bits;
#endif /* WITH_SSH1 */
+ if (ret == NULL)
+ return SSH_ERR_INVALID_ARGUMENT;
+
cp = *cpp;
switch (ret->type) {
@@ -3786,7 +3793,46 @@ sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type,
if ((pk = PEM_read_bio_PrivateKey(bio, NULL, NULL,
(char *)passphrase)) == NULL) {
- r = SSH_ERR_KEY_WRONG_PASSPHRASE;
+ unsigned long pem_err = ERR_peek_last_error();
+ int pem_reason = ERR_GET_REASON(pem_err);
+
+ /*
+ * Translate OpenSSL error codes to determine whether
+ * passphrase is required/incorrect.
+ */
+ switch (ERR_GET_LIB(pem_err)) {
+ case ERR_LIB_PEM:
+ switch (pem_reason) {
+ case PEM_R_BAD_PASSWORD_READ:
+ case PEM_R_PROBLEMS_GETTING_PASSWORD:
+ case PEM_R_BAD_DECRYPT:
+ r = SSH_ERR_KEY_WRONG_PASSPHRASE;
+ goto out;
+ default:
+ r = SSH_ERR_INVALID_FORMAT;
+ goto out;
+ }
+ case ERR_LIB_EVP:
+ switch (pem_reason) {
+ case EVP_R_BAD_DECRYPT:
+ r = SSH_ERR_KEY_WRONG_PASSPHRASE;
+ goto out;
+ case EVP_R_BN_DECODE_ERROR:
+ case EVP_R_DECODE_ERROR:
+#ifdef EVP_R_PRIVATE_KEY_DECODE_ERROR
+ case EVP_R_PRIVATE_KEY_DECODE_ERROR:
+#endif
+ r = SSH_ERR_INVALID_FORMAT;
+ goto out;
+ default:
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ case ERR_LIB_ASN1:
+ r = SSH_ERR_INVALID_FORMAT;
+ goto out;
+ }
+ r = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
if (pk->type == EVP_PKEY_RSA &&
@@ -3860,6 +3906,8 @@ int
sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type,
const char *passphrase, struct sshkey **keyp, char **commentp)
{
+ int r = SSH_ERR_INTERNAL_ERROR;
+
if (keyp != NULL)
*keyp = NULL;
if (commentp != NULL)
@@ -3882,9 +3930,11 @@ sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type,
return sshkey_parse_private2(blob, type, passphrase,
keyp, commentp);
case KEY_UNSPEC:
- if (sshkey_parse_private2(blob, type, passphrase, keyp,
- commentp) == 0)
- return 0;
+ r = sshkey_parse_private2(blob, type, passphrase, keyp,
+ commentp);
+ /* Do not fallback to PEM parser if only passphrase is wrong. */
+ if (r == 0 || r == SSH_ERR_KEY_WRONG_PASSPHRASE)
+ return r;
#ifdef WITH_OPENSSL
return sshkey_parse_private_pem_fileblob(blob, type,
passphrase, keyp);
OpenPOWER on IntegriCloud