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 c01da6c39..53a7674b5 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 },
@@ -195,14 +197,16 @@ sshkey_ecdsa_nid_from_name(const char *name)
195} 197}
196 198
197char * 199char *
198sshkey_alg_list(int certs_only, int plain_only, char sep) 200sshkey_alg_list(int certs_only, int plain_only, int include_sigonly, char sep)
199{ 201{
200 char *tmp, *ret = NULL; 202 char *tmp, *ret = NULL;
201 size_t nlen, rlen = 0; 203 size_t nlen, rlen = 0;
202 const struct keytype *kt; 204 const struct keytype *kt;
203 205
204 for (kt = keytypes; kt->type != -1; kt++) { 206 for (kt = keytypes; kt->type != -1; kt++) {
205 if (kt->name == NULL || kt->sigonly) 207 if (kt->name == NULL)
208 continue;
209 if (!include_sigonly && kt->sigonly)
206 continue; 210 continue;
207 if ((certs_only && !kt->cert) || (plain_only && kt->cert)) 211 if ((certs_only && !kt->cert) || (plain_only && kt->cert))
208 continue; 212 continue;
@@ -1237,6 +1241,9 @@ sshkey_read(struct sshkey *ret, char **cpp)
1237 u_long bits; 1241 u_long bits;
1238#endif /* WITH_SSH1 */ 1242#endif /* WITH_SSH1 */
1239 1243
1244 if (ret == NULL)
1245 return SSH_ERR_INVALID_ARGUMENT;
1246
1240 cp = *cpp; 1247 cp = *cpp;
1241 1248
1242 switch (ret->type) { 1249 switch (ret->type) {
@@ -3786,7 +3793,46 @@ sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type,
3786 3793
3787 if ((pk = PEM_read_bio_PrivateKey(bio, NULL, NULL, 3794 if ((pk = PEM_read_bio_PrivateKey(bio, NULL, NULL,
3788 (char *)passphrase)) == NULL) { 3795 (char *)passphrase)) == NULL) {
3789 r = SSH_ERR_KEY_WRONG_PASSPHRASE; 3796 unsigned long pem_err = ERR_peek_last_error();
3797 int pem_reason = ERR_GET_REASON(pem_err);
3798
3799 /*
3800 * Translate OpenSSL error codes to determine whether
3801 * passphrase is required/incorrect.
3802 */
3803 switch (ERR_GET_LIB(pem_err)) {
3804 case ERR_LIB_PEM:
3805 switch (pem_reason) {
3806 case PEM_R_BAD_PASSWORD_READ:
3807 case PEM_R_PROBLEMS_GETTING_PASSWORD:
3808 case PEM_R_BAD_DECRYPT:
3809 r = SSH_ERR_KEY_WRONG_PASSPHRASE;
3810 goto out;
3811 default:
3812 r = SSH_ERR_INVALID_FORMAT;
3813 goto out;
3814 }
3815 case ERR_LIB_EVP:
3816 switch (pem_reason) {
3817 case EVP_R_BAD_DECRYPT:
3818 r = SSH_ERR_KEY_WRONG_PASSPHRASE;
3819 goto out;
3820 case EVP_R_BN_DECODE_ERROR:
3821 case EVP_R_DECODE_ERROR:
3822#ifdef EVP_R_PRIVATE_KEY_DECODE_ERROR
3823 case EVP_R_PRIVATE_KEY_DECODE_ERROR:
3824#endif
3825 r = SSH_ERR_INVALID_FORMAT;
3826 goto out;
3827 default:
3828 r = SSH_ERR_LIBCRYPTO_ERROR;
3829 goto out;
3830 }
3831 case ERR_LIB_ASN1:
3832 r = SSH_ERR_INVALID_FORMAT;
3833 goto out;
3834 }
3835 r = SSH_ERR_LIBCRYPTO_ERROR;
3790 goto out; 3836 goto out;
3791 } 3837 }
3792 if (pk->type == EVP_PKEY_RSA && 3838 if (pk->type == EVP_PKEY_RSA &&
@@ -3860,6 +3906,8 @@ int
3860sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type, 3906sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type,
3861 const char *passphrase, struct sshkey **keyp, char **commentp) 3907 const char *passphrase, struct sshkey **keyp, char **commentp)
3862{ 3908{
3909 int r = SSH_ERR_INTERNAL_ERROR;
3910
3863 if (keyp != NULL) 3911 if (keyp != NULL)
3864 *keyp = NULL; 3912 *keyp = NULL;
3865 if (commentp != NULL) 3913 if (commentp != NULL)
@@ -3882,9 +3930,11 @@ sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type,
3882 return sshkey_parse_private2(blob, type, passphrase, 3930 return sshkey_parse_private2(blob, type, passphrase,
3883 keyp, commentp); 3931 keyp, commentp);
3884 case KEY_UNSPEC: 3932 case KEY_UNSPEC:
3885 if (sshkey_parse_private2(blob, type, passphrase, keyp, 3933 r = sshkey_parse_private2(blob, type, passphrase, keyp,
3886 commentp) == 0) 3934 commentp);
3887 return 0; 3935 /* Do not fallback to PEM parser if only passphrase is wrong. */
3936 if (r == 0 || r == SSH_ERR_KEY_WRONG_PASSPHRASE)
3937 return r;
3888#ifdef WITH_OPENSSL 3938#ifdef WITH_OPENSSL
3889 return sshkey_parse_private_pem_fileblob(blob, type, 3939 return sshkey_parse_private_pem_fileblob(blob, type,
3890 passphrase, keyp); 3940 passphrase, keyp);