summaryrefslogtreecommitdiff
path: root/sshkey.c
diff options
context:
space:
mode:
Diffstat (limited to 'sshkey.c')
-rw-r--r--sshkey.c64
1 files changed, 57 insertions, 7 deletions
diff --git a/sshkey.c b/sshkey.c
index 377d72fa9..540019898 100644
--- a/sshkey.c
+++ b/sshkey.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshkey.c,v 1.41 2016/10/24 01:09:17 dtucker Exp $ */ 1/* $OpenBSD: sshkey.c,v 1.45 2017/03/10 04:07:20 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
4 * Copyright (c) 2008 Alexander von Gernler. All rights reserved. 4 * Copyright (c) 2008 Alexander von Gernler. All rights reserved.
@@ -89,7 +89,9 @@ static const struct keytype keytypes[] = {
89 { "ssh-ed25519-cert-v01@openssh.com", "ED25519-CERT", 89 { "ssh-ed25519-cert-v01@openssh.com", "ED25519-CERT",
90 KEY_ED25519_CERT, 0, 1, 0 }, 90 KEY_ED25519_CERT, 0, 1, 0 },
91#ifdef WITH_OPENSSL 91#ifdef WITH_OPENSSL
92# ifdef WITH_SSH1
92 { NULL, "RSA1", KEY_RSA1, 0, 0, 0 }, 93 { NULL, "RSA1", KEY_RSA1, 0, 0, 0 },
94# endif
93 { "ssh-rsa", "RSA", KEY_RSA, 0, 0, 0 }, 95 { "ssh-rsa", "RSA", KEY_RSA, 0, 0, 0 },
94 { "rsa-sha2-256", "RSA", KEY_RSA, 0, 0, 1 }, 96 { "rsa-sha2-256", "RSA", KEY_RSA, 0, 0, 1 },
95 { "rsa-sha2-512", "RSA", KEY_RSA, 0, 0, 1 }, 97 { "rsa-sha2-512", "RSA", KEY_RSA, 0, 0, 1 },
@@ -196,14 +198,16 @@ sshkey_ecdsa_nid_from_name(const char *name)
196} 198}
197 199
198char * 200char *
199sshkey_alg_list(int certs_only, int plain_only, char sep) 201sshkey_alg_list(int certs_only, int plain_only, int include_sigonly, char sep)
200{ 202{
201 char *tmp, *ret = NULL; 203 char *tmp, *ret = NULL;
202 size_t nlen, rlen = 0; 204 size_t nlen, rlen = 0;
203 const struct keytype *kt; 205 const struct keytype *kt;
204 206
205 for (kt = keytypes; kt->type != -1; kt++) { 207 for (kt = keytypes; kt->type != -1; kt++) {
206 if (kt->name == NULL || kt->sigonly || kt->type == KEY_NULL) 208 if (kt->name == NULL || kt->type == KEY_NULL)
209 continue;
210 if (!include_sigonly && kt->sigonly)
207 continue; 211 continue;
208 if ((certs_only && !kt->cert) || (plain_only && kt->cert)) 212 if ((certs_only && !kt->cert) || (plain_only && kt->cert))
209 continue; 213 continue;
@@ -1238,6 +1242,9 @@ sshkey_read(struct sshkey *ret, char **cpp)
1238 u_long bits; 1242 u_long bits;
1239#endif /* WITH_SSH1 */ 1243#endif /* WITH_SSH1 */
1240 1244
1245 if (ret == NULL)
1246 return SSH_ERR_INVALID_ARGUMENT;
1247
1241 cp = *cpp; 1248 cp = *cpp;
1242 1249
1243 switch (ret->type) { 1250 switch (ret->type) {
@@ -3787,7 +3794,46 @@ sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type,
3787 3794
3788 if ((pk = PEM_read_bio_PrivateKey(bio, NULL, NULL, 3795 if ((pk = PEM_read_bio_PrivateKey(bio, NULL, NULL,
3789 (char *)passphrase)) == NULL) { 3796 (char *)passphrase)) == NULL) {
3790 r = SSH_ERR_KEY_WRONG_PASSPHRASE; 3797 unsigned long pem_err = ERR_peek_last_error();
3798 int pem_reason = ERR_GET_REASON(pem_err);
3799
3800 /*
3801 * Translate OpenSSL error codes to determine whether
3802 * passphrase is required/incorrect.
3803 */
3804 switch (ERR_GET_LIB(pem_err)) {
3805 case ERR_LIB_PEM:
3806 switch (pem_reason) {
3807 case PEM_R_BAD_PASSWORD_READ:
3808 case PEM_R_PROBLEMS_GETTING_PASSWORD:
3809 case PEM_R_BAD_DECRYPT:
3810 r = SSH_ERR_KEY_WRONG_PASSPHRASE;
3811 goto out;
3812 default:
3813 r = SSH_ERR_INVALID_FORMAT;
3814 goto out;
3815 }
3816 case ERR_LIB_EVP:
3817 switch (pem_reason) {
3818 case EVP_R_BAD_DECRYPT:
3819 r = SSH_ERR_KEY_WRONG_PASSPHRASE;
3820 goto out;
3821 case EVP_R_BN_DECODE_ERROR:
3822 case EVP_R_DECODE_ERROR:
3823#ifdef EVP_R_PRIVATE_KEY_DECODE_ERROR
3824 case EVP_R_PRIVATE_KEY_DECODE_ERROR:
3825#endif
3826 r = SSH_ERR_INVALID_FORMAT;
3827 goto out;
3828 default:
3829 r = SSH_ERR_LIBCRYPTO_ERROR;
3830 goto out;
3831 }
3832 case ERR_LIB_ASN1:
3833 r = SSH_ERR_INVALID_FORMAT;
3834 goto out;
3835 }
3836 r = SSH_ERR_LIBCRYPTO_ERROR;
3791 goto out; 3837 goto out;
3792 } 3838 }
3793 if (pk->type == EVP_PKEY_RSA && 3839 if (pk->type == EVP_PKEY_RSA &&
@@ -3861,6 +3907,8 @@ int
3861sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type, 3907sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type,
3862 const char *passphrase, struct sshkey **keyp, char **commentp) 3908 const char *passphrase, struct sshkey **keyp, char **commentp)
3863{ 3909{
3910 int r = SSH_ERR_INTERNAL_ERROR;
3911
3864 if (keyp != NULL) 3912 if (keyp != NULL)
3865 *keyp = NULL; 3913 *keyp = NULL;
3866 if (commentp != NULL) 3914 if (commentp != NULL)
@@ -3883,9 +3931,11 @@ sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type,
3883 return sshkey_parse_private2(blob, type, passphrase, 3931 return sshkey_parse_private2(blob, type, passphrase,
3884 keyp, commentp); 3932 keyp, commentp);
3885 case KEY_UNSPEC: 3933 case KEY_UNSPEC:
3886 if (sshkey_parse_private2(blob, type, passphrase, keyp, 3934 r = sshkey_parse_private2(blob, type, passphrase, keyp,
3887 commentp) == 0) 3935 commentp);
3888 return 0; 3936 /* Do not fallback to PEM parser if only passphrase is wrong. */
3937 if (r == 0 || r == SSH_ERR_KEY_WRONG_PASSPHRASE)
3938 return r;
3889#ifdef WITH_OPENSSL 3939#ifdef WITH_OPENSSL
3890 return sshkey_parse_private_pem_fileblob(blob, type, 3940 return sshkey_parse_private_pem_fileblob(blob, type,
3891 passphrase, keyp); 3941 passphrase, keyp);