diff options
author | Colin Watson <cjwatson@debian.org> | 2017-03-29 01:35:00 +0100 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2017-03-29 01:35:00 +0100 |
commit | 6fabaf6fd9b07cc8bc6a17c9c4a5b76849cfc874 (patch) | |
tree | b4377d09196e24e2c6f2c2128f66f92cf7891105 /sshkey.c | |
parent | 971a7653746a6972b907dfe0ce139c06e4a6f482 (diff) | |
parent | d38f05dbdd291212bc95ea80648b72b7177e9f4e (diff) |
Import openssh_7.5p1.orig.tar.gz
Diffstat (limited to 'sshkey.c')
-rw-r--r-- | sshkey.c | 64 |
1 files changed, 57 insertions, 7 deletions
@@ -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 | ||
197 | char * | 199 | char * |
198 | sshkey_alg_list(int certs_only, int plain_only, char sep) | 200 | sshkey_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 | |||
3860 | sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type, | 3906 | sshkey_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); |