summaryrefslogtreecommitdiff
path: root/sshkey.c
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2017-02-10 04:34:50 +0000
committerDamien Miller <djm@mindrot.org>2017-02-10 15:35:28 +1100
commit155d540d00ff55f063421ec182ec8ff2b7ab6cbe (patch)
tree069cdd4816c8f4f2e44dc85ac1dbb11e399d641e /sshkey.c
parenta287c5ad1e0bf9811c7b9221979b969255076019 (diff)
upstream commit
bring back r1.34 that was backed out for problems loading public keys: translate OpenSSL error codes to something more meaninful; bz#2522 reported by Jakub Jelen, ok dtucker@ with additional fix from Jakub Jelen to solve the backout. bz#2525 bz#2523 re-ok dtucker@ Upstream-ID: a9d5bc0306f4473d9b4f4484f880e95f3c1cc031
Diffstat (limited to 'sshkey.c')
-rw-r--r--sshkey.c51
1 files changed, 46 insertions, 5 deletions
diff --git a/sshkey.c b/sshkey.c
index c01da6c39..05675920f 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.42 2017/02/10 04:34:50 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.
@@ -3786,7 +3786,44 @@ sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type,
3786 3786
3787 if ((pk = PEM_read_bio_PrivateKey(bio, NULL, NULL, 3787 if ((pk = PEM_read_bio_PrivateKey(bio, NULL, NULL,
3788 (char *)passphrase)) == NULL) { 3788 (char *)passphrase)) == NULL) {
3789 r = SSH_ERR_KEY_WRONG_PASSPHRASE; 3789 unsigned long pem_err = ERR_peek_last_error();
3790 int pem_reason = ERR_GET_REASON(pem_err);
3791
3792 /*
3793 * Translate OpenSSL error codes to determine whether
3794 * passphrase is required/incorrect.
3795 */
3796 switch (ERR_GET_LIB(pem_err)) {
3797 case ERR_LIB_PEM:
3798 switch (pem_reason) {
3799 case PEM_R_BAD_PASSWORD_READ:
3800 case PEM_R_PROBLEMS_GETTING_PASSWORD:
3801 case PEM_R_BAD_DECRYPT:
3802 r = SSH_ERR_KEY_WRONG_PASSPHRASE;
3803 goto out;
3804 default:
3805 r = SSH_ERR_INVALID_FORMAT;
3806 goto out;
3807 }
3808 case ERR_LIB_EVP:
3809 switch (pem_reason) {
3810 case EVP_R_BAD_DECRYPT:
3811 r = SSH_ERR_KEY_WRONG_PASSPHRASE;
3812 goto out;
3813 case EVP_R_BN_DECODE_ERROR:
3814 case EVP_R_DECODE_ERROR:
3815 case EVP_R_PRIVATE_KEY_DECODE_ERROR:
3816 r = SSH_ERR_INVALID_FORMAT;
3817 goto out;
3818 default:
3819 r = SSH_ERR_LIBCRYPTO_ERROR;
3820 goto out;
3821 }
3822 case ERR_LIB_ASN1:
3823 r = SSH_ERR_INVALID_FORMAT;
3824 goto out;
3825 }
3826 r = SSH_ERR_LIBCRYPTO_ERROR;
3790 goto out; 3827 goto out;
3791 } 3828 }
3792 if (pk->type == EVP_PKEY_RSA && 3829 if (pk->type == EVP_PKEY_RSA &&
@@ -3860,6 +3897,8 @@ int
3860sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type, 3897sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type,
3861 const char *passphrase, struct sshkey **keyp, char **commentp) 3898 const char *passphrase, struct sshkey **keyp, char **commentp)
3862{ 3899{
3900 int r = SSH_ERR_INTERNAL_ERROR;
3901
3863 if (keyp != NULL) 3902 if (keyp != NULL)
3864 *keyp = NULL; 3903 *keyp = NULL;
3865 if (commentp != NULL) 3904 if (commentp != NULL)
@@ -3882,9 +3921,11 @@ sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type,
3882 return sshkey_parse_private2(blob, type, passphrase, 3921 return sshkey_parse_private2(blob, type, passphrase,
3883 keyp, commentp); 3922 keyp, commentp);
3884 case KEY_UNSPEC: 3923 case KEY_UNSPEC:
3885 if (sshkey_parse_private2(blob, type, passphrase, keyp, 3924 r = sshkey_parse_private2(blob, type, passphrase, keyp,
3886 commentp) == 0) 3925 commentp);
3887 return 0; 3926 /* Do not fallback to PEM parser if only passphrase is wrong. */
3927 if (r == 0 || r == SSH_ERR_KEY_WRONG_PASSPHRASE)
3928 return r;
3888#ifdef WITH_OPENSSL 3929#ifdef WITH_OPENSSL
3889 return sshkey_parse_private_pem_fileblob(blob, type, 3930 return sshkey_parse_private_pem_fileblob(blob, type,
3890 passphrase, keyp); 3931 passphrase, keyp);