- djm@cvs.openbsd.org 2013/12/30 23:52:28
[auth2-hostbased.c auth2-pubkey.c compat.c compat.h ssh-rsa.c] [sshconnect.c sshconnect2.c sshd.c] refuse RSA keys from old proprietary clients/servers that use the obsolete RSA+MD5 signature scheme. it will still be possible to connect with these clients/servers but only DSA keys will be accepted, and we'll deprecate them entirely in a future release. ok markus@
This commit is contained in:
parent
9f4c8e797e
commit
324541e526
10
ChangeLog
10
ChangeLog
|
@ -1,3 +1,13 @@
|
||||||
|
20131231
|
||||||
|
- (djm) OpenBSD CVS Sync
|
||||||
|
- djm@cvs.openbsd.org 2013/12/30 23:52:28
|
||||||
|
[auth2-hostbased.c auth2-pubkey.c compat.c compat.h ssh-rsa.c]
|
||||||
|
[sshconnect.c sshconnect2.c sshd.c]
|
||||||
|
refuse RSA keys from old proprietary clients/servers that use the
|
||||||
|
obsolete RSA+MD5 signature scheme. it will still be possible to connect
|
||||||
|
with these clients/servers but only DSA keys will be accepted, and we'll
|
||||||
|
deprecate them entirely in a future release. ok markus@
|
||||||
|
|
||||||
20131229
|
20131229
|
||||||
- (djm) [loginrec.c] Check for username truncation when looking up lastlog
|
- (djm) [loginrec.c] Check for username truncation when looking up lastlog
|
||||||
entries
|
entries
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: auth2-hostbased.c,v 1.16 2013/06/21 00:34:49 djm Exp $ */
|
/* $OpenBSD: auth2-hostbased.c,v 1.17 2013/12/30 23:52:27 djm Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||||
*
|
*
|
||||||
|
@ -100,6 +100,12 @@ userauth_hostbased(Authctxt *authctxt)
|
||||||
"(received %d, expected %d)", key->type, pktype);
|
"(received %d, expected %d)", key->type, pktype);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
if (key_type_plain(key->type) == KEY_RSA &&
|
||||||
|
(datafellows & SSH_BUG_RSASIGMD5) != 0) {
|
||||||
|
error("Refusing RSA key because peer uses unsafe "
|
||||||
|
"signature format");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
service = datafellows & SSH_BUG_HBSERVICE ? "ssh-userauth" :
|
service = datafellows & SSH_BUG_HBSERVICE ? "ssh-userauth" :
|
||||||
authctxt->service;
|
authctxt->service;
|
||||||
buffer_init(&b);
|
buffer_init(&b);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: auth2-pubkey.c,v 1.38 2013/06/21 00:34:49 djm Exp $ */
|
/* $OpenBSD: auth2-pubkey.c,v 1.39 2013/12/30 23:52:27 djm Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||||
*
|
*
|
||||||
|
@ -116,6 +116,12 @@ userauth_pubkey(Authctxt *authctxt)
|
||||||
"(received %d, expected %d)", key->type, pktype);
|
"(received %d, expected %d)", key->type, pktype);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
if (key_type_plain(key->type) == KEY_RSA &&
|
||||||
|
(datafellows & SSH_BUG_RSASIGMD5) != 0) {
|
||||||
|
logit("Refusing RSA key because client uses unsafe "
|
||||||
|
"signature scheme");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
if (have_sig) {
|
if (have_sig) {
|
||||||
sig = packet_get_string(&slen);
|
sig = packet_get_string(&slen);
|
||||||
packet_check_eom();
|
packet_check_eom();
|
||||||
|
|
61
compat.c
61
compat.c
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: compat.c,v 1.81 2013/05/17 00:13:13 djm Exp $ */
|
/* $OpenBSD: compat.c,v 1.82 2013/12/30 23:52:27 djm Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved.
|
* Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved.
|
||||||
*
|
*
|
||||||
|
@ -171,8 +171,9 @@ compat_datafellows(const char *version)
|
||||||
for (i = 0; check[i].pat; i++) {
|
for (i = 0; check[i].pat; i++) {
|
||||||
if (match_pattern_list(version, check[i].pat,
|
if (match_pattern_list(version, check[i].pat,
|
||||||
strlen(check[i].pat), 0) == 1) {
|
strlen(check[i].pat), 0) == 1) {
|
||||||
debug("match: %s pat %s", version, check[i].pat);
|
|
||||||
datafellows = check[i].bugs;
|
datafellows = check[i].bugs;
|
||||||
|
debug("match: %s pat %s compat 0x%08x",
|
||||||
|
version, check[i].pat, datafellows);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -208,33 +209,59 @@ proto_spec(const char *spec)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
/*
|
||||||
compat_cipher_proposal(char *cipher_prop)
|
* Filters a proposal string, excluding any algorithm matching the 'filter'
|
||||||
|
* pattern list.
|
||||||
|
*/
|
||||||
|
static char *
|
||||||
|
filter_proposal(char *proposal, const char *filter)
|
||||||
{
|
{
|
||||||
Buffer b;
|
Buffer b;
|
||||||
char *orig_prop, *fix_ciphers;
|
char *orig_prop, *fix_prop;
|
||||||
char *cp, *tmp;
|
char *cp, *tmp;
|
||||||
|
|
||||||
if (!(datafellows & SSH_BUG_BIGENDIANAES))
|
|
||||||
return(cipher_prop);
|
|
||||||
|
|
||||||
buffer_init(&b);
|
buffer_init(&b);
|
||||||
tmp = orig_prop = xstrdup(cipher_prop);
|
tmp = orig_prop = xstrdup(proposal);
|
||||||
while ((cp = strsep(&tmp, ",")) != NULL) {
|
while ((cp = strsep(&tmp, ",")) != NULL) {
|
||||||
if (strncmp(cp, "aes", 3) != 0) {
|
if (match_pattern_list(cp, filter, strlen(cp), 0) != 1) {
|
||||||
if (buffer_len(&b) > 0)
|
if (buffer_len(&b) > 0)
|
||||||
buffer_append(&b, ",", 1);
|
buffer_append(&b, ",", 1);
|
||||||
buffer_append(&b, cp, strlen(cp));
|
buffer_append(&b, cp, strlen(cp));
|
||||||
}
|
} else
|
||||||
|
debug2("Compat: skipping algorithm \"%s\"", cp);
|
||||||
}
|
}
|
||||||
buffer_append(&b, "\0", 1);
|
buffer_append(&b, "\0", 1);
|
||||||
fix_ciphers = xstrdup(buffer_ptr(&b));
|
fix_prop = xstrdup(buffer_ptr(&b));
|
||||||
buffer_free(&b);
|
buffer_free(&b);
|
||||||
free(orig_prop);
|
free(orig_prop);
|
||||||
debug2("Original cipher proposal: %s", cipher_prop);
|
|
||||||
debug2("Compat cipher proposal: %s", fix_ciphers);
|
|
||||||
if (!*fix_ciphers)
|
|
||||||
fatal("No available ciphers found.");
|
|
||||||
|
|
||||||
return(fix_ciphers);
|
return fix_prop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
compat_cipher_proposal(char *cipher_prop)
|
||||||
|
{
|
||||||
|
if (!(datafellows & SSH_BUG_BIGENDIANAES))
|
||||||
|
return cipher_prop;
|
||||||
|
debug2("%s: original cipher proposal: %s", __func__, cipher_prop);
|
||||||
|
cipher_prop = filter_proposal(cipher_prop, "aes*");
|
||||||
|
debug2("%s: compat cipher proposal: %s", __func__, cipher_prop);
|
||||||
|
if (*cipher_prop == '\0')
|
||||||
|
fatal("No supported ciphers found");
|
||||||
|
return cipher_prop;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char *
|
||||||
|
compat_pkalg_proposal(char *pkalg_prop)
|
||||||
|
{
|
||||||
|
if (!(datafellows & SSH_BUG_RSASIGMD5))
|
||||||
|
return pkalg_prop;
|
||||||
|
debug2("%s: original public key proposal: %s", __func__, pkalg_prop);
|
||||||
|
pkalg_prop = filter_proposal(pkalg_prop, "ssh-rsa");
|
||||||
|
debug2("%s: compat public key proposal: %s", __func__, pkalg_prop);
|
||||||
|
if (*pkalg_prop == '\0')
|
||||||
|
fatal("No supported PK algorithms found");
|
||||||
|
return pkalg_prop;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
3
compat.h
3
compat.h
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: compat.h,v 1.43 2011/09/23 07:45:05 markus Exp $ */
|
/* $OpenBSD: compat.h,v 1.44 2013/12/30 23:52:27 djm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2000, 2001 Markus Friedl. All rights reserved.
|
* Copyright (c) 1999, 2000, 2001 Markus Friedl. All rights reserved.
|
||||||
|
@ -65,6 +65,7 @@ void enable_compat20(void);
|
||||||
void compat_datafellows(const char *);
|
void compat_datafellows(const char *);
|
||||||
int proto_spec(const char *);
|
int proto_spec(const char *);
|
||||||
char *compat_cipher_proposal(char *);
|
char *compat_cipher_proposal(char *);
|
||||||
|
char *compat_pkalg_proposal(char *);
|
||||||
|
|
||||||
extern int compat13;
|
extern int compat13;
|
||||||
extern int compat20;
|
extern int compat20;
|
||||||
|
|
23
ssh-rsa.c
23
ssh-rsa.c
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: ssh-rsa.c,v 1.48 2013/12/27 22:37:18 djm Exp $ */
|
/* $OpenBSD: ssh-rsa.c,v 1.49 2013/12/30 23:52:27 djm Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2000, 2003 Markus Friedl <markus@openbsd.org>
|
* Copyright (c) 2000, 2003 Markus Friedl <markus@openbsd.org>
|
||||||
*
|
*
|
||||||
|
@ -53,7 +53,7 @@ ssh_rsa_sign(const Key *key, u_char **sigp, u_int *lenp,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
nid = (datafellows & SSH_BUG_RSASIGMD5) ? NID_md5 : NID_sha1;
|
nid = NID_sha1;
|
||||||
if ((evp_md = EVP_get_digestbynid(nid)) == NULL) {
|
if ((evp_md = EVP_get_digestbynid(nid)) == NULL) {
|
||||||
error("%s: EVP_get_digestbynid %d failed", __func__, nid);
|
error("%s: EVP_get_digestbynid %d failed", __func__, nid);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -161,7 +161,7 @@ ssh_rsa_verify(const Key *key, const u_char *signature, u_int signaturelen,
|
||||||
memset(sigblob, 0, diff);
|
memset(sigblob, 0, diff);
|
||||||
len = modlen;
|
len = modlen;
|
||||||
}
|
}
|
||||||
nid = (datafellows & SSH_BUG_RSASIGMD5) ? NID_md5 : NID_sha1;
|
nid = NID_sha1;
|
||||||
if ((evp_md = EVP_get_digestbynid(nid)) == NULL) {
|
if ((evp_md = EVP_get_digestbynid(nid)) == NULL) {
|
||||||
error("%s: EVP_get_digestbynid %d failed", __func__, nid);
|
error("%s: EVP_get_digestbynid %d failed", __func__, nid);
|
||||||
free(sigblob);
|
free(sigblob);
|
||||||
|
@ -196,18 +196,6 @@ static const u_char id_sha1[] = {
|
||||||
0x05, 0x00, /* NULL */
|
0x05, 0x00, /* NULL */
|
||||||
0x04, 0x14 /* Octet string, length 0x14 (20), followed by sha1 hash */
|
0x04, 0x14 /* Octet string, length 0x14 (20), followed by sha1 hash */
|
||||||
};
|
};
|
||||||
/*
|
|
||||||
* id-md5 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840)
|
|
||||||
* rsadsi(113549) digestAlgorithm(2) 5 }
|
|
||||||
*/
|
|
||||||
static const u_char id_md5[] = {
|
|
||||||
0x30, 0x20, /* type Sequence, length 0x20 (32) */
|
|
||||||
0x30, 0x0c, /* type Sequence, length 0x0c (12) */
|
|
||||||
0x06, 0x08, /* type OID, length 0x08 */
|
|
||||||
0x2a, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05, /* id-md5 */
|
|
||||||
0x05, 0x00, /* NULL */
|
|
||||||
0x04, 0x10 /* Octet string, length 0x10 (16), followed by md5 hash */
|
|
||||||
};
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
openssh_RSA_verify(int type, u_char *hash, u_int hashlen,
|
openssh_RSA_verify(int type, u_char *hash, u_int hashlen,
|
||||||
|
@ -225,11 +213,6 @@ openssh_RSA_verify(int type, u_char *hash, u_int hashlen,
|
||||||
oidlen = sizeof(id_sha1);
|
oidlen = sizeof(id_sha1);
|
||||||
hlen = 20;
|
hlen = 20;
|
||||||
break;
|
break;
|
||||||
case NID_md5:
|
|
||||||
oid = id_md5;
|
|
||||||
oidlen = sizeof(id_md5);
|
|
||||||
hlen = 16;
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: sshconnect.c,v 1.242 2013/12/29 05:57:02 djm Exp $ */
|
/* $OpenBSD: sshconnect.c,v 1.243 2013/12/30 23:52:27 djm Exp $ */
|
||||||
/*
|
/*
|
||||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||||
|
@ -662,6 +662,9 @@ ssh_exchange_identification(int timeout_ms)
|
||||||
fatal("Protocol major versions differ: %d vs. %d",
|
fatal("Protocol major versions differ: %d vs. %d",
|
||||||
(options.protocol & SSH_PROTO_2) ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1,
|
(options.protocol & SSH_PROTO_2) ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1,
|
||||||
remote_major);
|
remote_major);
|
||||||
|
if ((datafellows & SSH_BUG_RSASIGMD5) != 0)
|
||||||
|
logit("Server version \"%.100s\" uses unsafe RSA signature "
|
||||||
|
"scheme; disabling use of RSA keys", remote_version);
|
||||||
if (!client_banner_sent)
|
if (!client_banner_sent)
|
||||||
send_client_banner(connection_out, minor1);
|
send_client_banner(connection_out, minor1);
|
||||||
chop(server_version_string);
|
chop(server_version_string);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: sshconnect2.c,v 1.199 2013/11/02 21:59:15 markus Exp $ */
|
/* $OpenBSD: sshconnect2.c,v 1.200 2013/12/30 23:52:28 djm Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||||
* Copyright (c) 2008 Damien Miller. All rights reserved.
|
* Copyright (c) 2008 Damien Miller. All rights reserved.
|
||||||
|
@ -188,11 +188,12 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port)
|
||||||
}
|
}
|
||||||
if (options.hostkeyalgorithms != NULL)
|
if (options.hostkeyalgorithms != NULL)
|
||||||
myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] =
|
myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] =
|
||||||
options.hostkeyalgorithms;
|
compat_pkalg_proposal(options.hostkeyalgorithms);
|
||||||
else {
|
else {
|
||||||
/* Prefer algorithms that we already have keys for */
|
/* Prefer algorithms that we already have keys for */
|
||||||
myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] =
|
myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] =
|
||||||
order_hostkeyalgs(host, hostaddr, port);
|
compat_pkalg_proposal(
|
||||||
|
order_hostkeyalgs(host, hostaddr, port));
|
||||||
}
|
}
|
||||||
if (options.kex_algorithms != NULL)
|
if (options.kex_algorithms != NULL)
|
||||||
myproposal[PROPOSAL_KEX_ALGS] = options.kex_algorithms;
|
myproposal[PROPOSAL_KEX_ALGS] = options.kex_algorithms;
|
||||||
|
@ -1489,17 +1490,31 @@ userauth_pubkey(Authctxt *authctxt)
|
||||||
* encrypted keys we cannot do this and have to load the
|
* encrypted keys we cannot do this and have to load the
|
||||||
* private key instead
|
* private key instead
|
||||||
*/
|
*/
|
||||||
if (id->key && id->key->type != KEY_RSA1) {
|
if (id->key != NULL) {
|
||||||
debug("Offering %s public key: %s", key_type(id->key),
|
if (key_type_plain(id->key->type) == KEY_RSA &&
|
||||||
id->filename);
|
(datafellows & SSH_BUG_RSASIGMD5) != 0) {
|
||||||
sent = send_pubkey_test(authctxt, id);
|
debug("Skipped %s key %s for RSA/MD5 server",
|
||||||
} else if (id->key == NULL) {
|
key_type(id->key), id->filename);
|
||||||
|
} else if (id->key->type != KEY_RSA1) {
|
||||||
|
debug("Offering %s public key: %s",
|
||||||
|
key_type(id->key), id->filename);
|
||||||
|
sent = send_pubkey_test(authctxt, id);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
debug("Trying private key: %s", id->filename);
|
debug("Trying private key: %s", id->filename);
|
||||||
id->key = load_identity_file(id->filename,
|
id->key = load_identity_file(id->filename,
|
||||||
id->userprovided);
|
id->userprovided);
|
||||||
if (id->key != NULL) {
|
if (id->key != NULL) {
|
||||||
id->isprivate = 1;
|
id->isprivate = 1;
|
||||||
sent = sign_and_send_pubkey(authctxt, id);
|
if (key_type_plain(id->key->type) == KEY_RSA &&
|
||||||
|
(datafellows & SSH_BUG_RSASIGMD5) != 0) {
|
||||||
|
debug("Skipped %s key %s for RSA/MD5 "
|
||||||
|
"server", key_type(id->key),
|
||||||
|
id->filename);
|
||||||
|
} else {
|
||||||
|
sent = sign_and_send_pubkey(
|
||||||
|
authctxt, id);
|
||||||
|
}
|
||||||
key_free(id->key);
|
key_free(id->key);
|
||||||
id->key = NULL;
|
id->key = NULL;
|
||||||
}
|
}
|
||||||
|
|
13
sshd.c
13
sshd.c
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: sshd.c,v 1.412 2013/12/06 13:39:49 markus Exp $ */
|
/* $OpenBSD: sshd.c,v 1.413 2013/12/30 23:52:28 djm Exp $ */
|
||||||
/*
|
/*
|
||||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||||
|
@ -492,17 +492,19 @@ sshd_exchange_identification(int sock_in, int sock_out)
|
||||||
|
|
||||||
compat_datafellows(remote_version);
|
compat_datafellows(remote_version);
|
||||||
|
|
||||||
if (datafellows & SSH_BUG_PROBE) {
|
if ((datafellows & SSH_BUG_PROBE) != 0) {
|
||||||
logit("probed from %s with %s. Don't panic.",
|
logit("probed from %s with %s. Don't panic.",
|
||||||
get_remote_ipaddr(), client_version_string);
|
get_remote_ipaddr(), client_version_string);
|
||||||
cleanup_exit(255);
|
cleanup_exit(255);
|
||||||
}
|
}
|
||||||
|
if ((datafellows & SSH_BUG_SCANNER) != 0) {
|
||||||
if (datafellows & SSH_BUG_SCANNER) {
|
|
||||||
logit("scanned from %s with %s. Don't panic.",
|
logit("scanned from %s with %s. Don't panic.",
|
||||||
get_remote_ipaddr(), client_version_string);
|
get_remote_ipaddr(), client_version_string);
|
||||||
cleanup_exit(255);
|
cleanup_exit(255);
|
||||||
}
|
}
|
||||||
|
if ((datafellows & SSH_BUG_RSASIGMD5) != 0)
|
||||||
|
logit("Client version \"%.100s\" uses unsafe RSA signature "
|
||||||
|
"scheme; disabling use of RSA keys", remote_version);
|
||||||
|
|
||||||
mismatch = 0;
|
mismatch = 0;
|
||||||
switch (remote_major) {
|
switch (remote_major) {
|
||||||
|
@ -2446,7 +2448,8 @@ do_ssh2_kex(void)
|
||||||
packet_set_rekey_limits((u_int32_t)options.rekey_limit,
|
packet_set_rekey_limits((u_int32_t)options.rekey_limit,
|
||||||
(time_t)options.rekey_interval);
|
(time_t)options.rekey_interval);
|
||||||
|
|
||||||
myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = list_hostkey_types();
|
myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal(
|
||||||
|
list_hostkey_types());
|
||||||
|
|
||||||
/* start key exchange */
|
/* start key exchange */
|
||||||
kex = kex_setup(myproposal);
|
kex = kex_setup(myproposal);
|
||||||
|
|
Loading…
Reference in New Issue