- provos@cvs.openbsd.org 2001/03/27 17:46:50
[compat.c compat.h dh.c dh.h ssh2.h sshconnect2.c sshd.c version.h] make dh group exchange more flexible, allow min and max group size, okay markus@, deraadt@
This commit is contained in:
parent
60a4381f1a
commit
df221391e6
|
@ -16,6 +16,10 @@
|
||||||
[compat.c compat.h ssh-rsa.c]
|
[compat.c compat.h ssh-rsa.c]
|
||||||
some older systems use NID_md5 instead of NID_sha1 for RSASSA-PKCS1-v1_5
|
some older systems use NID_md5 instead of NID_sha1 for RSASSA-PKCS1-v1_5
|
||||||
signatures in SSH protocol 2, ok djm@
|
signatures in SSH protocol 2, ok djm@
|
||||||
|
- provos@cvs.openbsd.org 2001/03/27 17:46:50
|
||||||
|
[compat.c compat.h dh.c dh.h ssh2.h sshconnect2.c sshd.c version.h]
|
||||||
|
make dh group exchange more flexible, allow min and max group size,
|
||||||
|
okay markus@, deraadt@
|
||||||
|
|
||||||
20010328
|
20010328
|
||||||
- (djm) Reorder tests and library inclusion for Krb4/AFS to try to
|
- (djm) Reorder tests and library inclusion for Krb4/AFS to try to
|
||||||
|
@ -4754,4 +4758,4 @@
|
||||||
- Wrote replacements for strlcpy and mkdtemp
|
- Wrote replacements for strlcpy and mkdtemp
|
||||||
- Released 1.0pre1
|
- Released 1.0pre1
|
||||||
|
|
||||||
$Id: ChangeLog,v 1.1030 2001/03/29 00:32:56 mouring Exp $
|
$Id: ChangeLog,v 1.1031 2001/03/29 00:36:16 mouring Exp $
|
||||||
|
|
12
compat.c
12
compat.c
|
@ -23,7 +23,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
RCSID("$OpenBSD: compat.c,v 1.41 2001/03/27 10:57:00 markus Exp $");
|
RCSID("$OpenBSD: compat.c,v 1.42 2001/03/27 17:46:49 provos Exp $");
|
||||||
|
|
||||||
#ifdef HAVE_LIBPCRE
|
#ifdef HAVE_LIBPCRE
|
||||||
# include <pcreposix.h>
|
# include <pcreposix.h>
|
||||||
|
@ -68,10 +68,14 @@ compat_datafellows(const char *version)
|
||||||
int bugs;
|
int bugs;
|
||||||
} check[] = {
|
} check[] = {
|
||||||
{ "^OpenSSH[-_]2\\.[012]",
|
{ "^OpenSSH[-_]2\\.[012]",
|
||||||
SSH_OLD_SESSIONID|SSH_BUG_BANNER },
|
SSH_OLD_SESSIONID|SSH_BUG_BANNER|
|
||||||
{ "^OpenSSH_2\\.3\\.0", SSH_BUG_BANNER|SSH_BUG_BIGENDIANAES },
|
SSH_OLD_DHGEX },
|
||||||
|
{ "^OpenSSH_2\\.3\\.0", SSH_BUG_BANNER|SSH_BUG_BIGENDIANAES|
|
||||||
|
SSH_OLD_DHGEX},
|
||||||
{ "^OpenSSH_2\\.5\\.[01]p1",
|
{ "^OpenSSH_2\\.5\\.[01]p1",
|
||||||
SSH_BUG_BIGENDIANAES },
|
SSH_BUG_BIGENDIANAES|SSH_OLD_DHGEX },
|
||||||
|
{ "^OpenSSH_2\\.5\\.[012]",
|
||||||
|
SSH_OLD_DHGEX },
|
||||||
{ "^OpenSSH", 0 },
|
{ "^OpenSSH", 0 },
|
||||||
{ "MindTerm", 0 },
|
{ "MindTerm", 0 },
|
||||||
{ "^2\\.1\\.0", SSH_BUG_SIGBLOB|SSH_BUG_HMAC|
|
{ "^2\\.1\\.0", SSH_BUG_SIGBLOB|SSH_BUG_HMAC|
|
||||||
|
|
3
compat.h
3
compat.h
|
@ -21,7 +21,7 @@
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
/* RCSID("$OpenBSD: compat.h,v 1.20 2001/03/27 10:57:00 markus Exp $"); */
|
/* RCSID("$OpenBSD: compat.h,v 1.21 2001/03/27 17:46:49 provos Exp $"); */
|
||||||
|
|
||||||
#ifndef COMPAT_H
|
#ifndef COMPAT_H
|
||||||
#define COMPAT_H
|
#define COMPAT_H
|
||||||
|
@ -45,6 +45,7 @@
|
||||||
#define SSH_BUG_SCANNER 0x0800
|
#define SSH_BUG_SCANNER 0x0800
|
||||||
#define SSH_BUG_BIGENDIANAES 0x1000
|
#define SSH_BUG_BIGENDIANAES 0x1000
|
||||||
#define SSH_BUG_RSASIGMD5 0x2000
|
#define SSH_BUG_RSASIGMD5 0x2000
|
||||||
|
#define SSH_OLD_DHGEX 0x4000
|
||||||
|
|
||||||
void enable_compat13(void);
|
void enable_compat13(void);
|
||||||
void enable_compat20(void);
|
void enable_compat20(void);
|
||||||
|
|
19
dh.c
19
dh.c
|
@ -23,7 +23,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
RCSID("$OpenBSD: dh.c,v 1.8 2001/03/05 17:58:22 stevesk Exp $");
|
RCSID("$OpenBSD: dh.c,v 1.9 2001/03/27 17:46:49 provos Exp $");
|
||||||
|
|
||||||
#include "xmalloc.h"
|
#include "xmalloc.h"
|
||||||
|
|
||||||
|
@ -69,6 +69,8 @@ parse_prime(int linenum, char *line, struct dhgroup *dhg)
|
||||||
if (cp == NULL || *strsize == '\0' ||
|
if (cp == NULL || *strsize == '\0' ||
|
||||||
(dhg->size = atoi(strsize)) == 0)
|
(dhg->size = atoi(strsize)) == 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
/* The whole group is one bit larger */
|
||||||
|
dhg->size++;
|
||||||
gen = strsep(&cp, " "); /* gen */
|
gen = strsep(&cp, " "); /* gen */
|
||||||
if (cp == NULL || *gen == '\0')
|
if (cp == NULL || *gen == '\0')
|
||||||
goto fail;
|
goto fail;
|
||||||
|
@ -95,7 +97,7 @@ parse_prime(int linenum, char *line, struct dhgroup *dhg)
|
||||||
}
|
}
|
||||||
|
|
||||||
DH *
|
DH *
|
||||||
choose_dh(int minbits)
|
choose_dh(int min, int wantbits, int max)
|
||||||
{
|
{
|
||||||
FILE *f;
|
FILE *f;
|
||||||
char line[1024];
|
char line[1024];
|
||||||
|
@ -118,8 +120,11 @@ choose_dh(int minbits)
|
||||||
BN_free(dhg.g);
|
BN_free(dhg.g);
|
||||||
BN_free(dhg.p);
|
BN_free(dhg.p);
|
||||||
|
|
||||||
if ((dhg.size > minbits && dhg.size < best) ||
|
if (dhg.size > max || dhg.size < min)
|
||||||
(dhg.size > best && best < minbits)) {
|
continue;
|
||||||
|
|
||||||
|
if ((dhg.size > wantbits && dhg.size < best) ||
|
||||||
|
(dhg.size > best && best < wantbits)) {
|
||||||
best = dhg.size;
|
best = dhg.size;
|
||||||
bestcount = 0;
|
bestcount = 0;
|
||||||
}
|
}
|
||||||
|
@ -129,8 +134,8 @@ choose_dh(int minbits)
|
||||||
fclose (f);
|
fclose (f);
|
||||||
|
|
||||||
if (bestcount == 0) {
|
if (bestcount == 0) {
|
||||||
log("WARNING: no primes in %s, using old prime", _PATH_DH_PRIMES);
|
log("WARNING: no suitable primes in %s", _PATH_DH_PRIMES);
|
||||||
return (dh_new_group1());
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
f = fopen(_PATH_DH_PRIMES, "r");
|
f = fopen(_PATH_DH_PRIMES, "r");
|
||||||
|
@ -143,6 +148,8 @@ choose_dh(int minbits)
|
||||||
while (fgets(line, sizeof(line), f)) {
|
while (fgets(line, sizeof(line), f)) {
|
||||||
if (!parse_prime(linenum, line, &dhg))
|
if (!parse_prime(linenum, line, &dhg))
|
||||||
continue;
|
continue;
|
||||||
|
if (dhg.size > max || dhg.size < min)
|
||||||
|
continue;
|
||||||
if (dhg.size != best)
|
if (dhg.size != best)
|
||||||
continue;
|
continue;
|
||||||
if (linenum++ != which) {
|
if (linenum++ != which) {
|
||||||
|
|
7
dh.h
7
dh.h
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: dh.h,v 1.2 2001/01/29 01:58:15 niklas Exp $ */
|
/* $OpenBSD: dh.h,v 1.3 2001/03/27 17:46:49 provos Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2000 Niels Provos. All rights reserved.
|
* Copyright (c) 2000 Niels Provos. All rights reserved.
|
||||||
|
@ -32,6 +32,9 @@ struct dhgroup {
|
||||||
BIGNUM *p;
|
BIGNUM *p;
|
||||||
};
|
};
|
||||||
|
|
||||||
DH *choose_dh(int minbits);
|
DH *choose_dh(int min, int nbits, int max);
|
||||||
|
|
||||||
|
#define DH_GRP_MIN 1024
|
||||||
|
#define DH_GRP_MAX 8192
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
5
ssh2.h
5
ssh2.h
|
@ -52,7 +52,7 @@
|
||||||
*
|
*
|
||||||
* 192-255 Local extensions
|
* 192-255 Local extensions
|
||||||
*/
|
*/
|
||||||
/* RCSID("$OpenBSD: ssh2.h,v 1.5 2000/10/11 04:02:17 provos Exp $"); */
|
/* RCSID("$OpenBSD: ssh2.h,v 1.6 2001/03/27 17:46:49 provos Exp $"); */
|
||||||
|
|
||||||
/* transport layer: generic */
|
/* transport layer: generic */
|
||||||
|
|
||||||
|
@ -74,10 +74,11 @@
|
||||||
#define SSH2_MSG_KEXDH_REPLY 31
|
#define SSH2_MSG_KEXDH_REPLY 31
|
||||||
|
|
||||||
/* dh-group-exchange */
|
/* dh-group-exchange */
|
||||||
#define SSH2_MSG_KEX_DH_GEX_REQUEST 30
|
#define SSH2_MSG_KEX_DH_GEX_REQUEST_OLD 30
|
||||||
#define SSH2_MSG_KEX_DH_GEX_GROUP 31
|
#define SSH2_MSG_KEX_DH_GEX_GROUP 31
|
||||||
#define SSH2_MSG_KEX_DH_GEX_INIT 32
|
#define SSH2_MSG_KEX_DH_GEX_INIT 32
|
||||||
#define SSH2_MSG_KEX_DH_GEX_REPLY 33
|
#define SSH2_MSG_KEX_DH_GEX_REPLY 33
|
||||||
|
#define SSH2_MSG_KEX_DH_GEX_REQUEST 34
|
||||||
|
|
||||||
/* user authentication: generic */
|
/* user authentication: generic */
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
RCSID("$OpenBSD: sshconnect2.c,v 1.56 2001/03/26 08:07:09 markus Exp $");
|
RCSID("$OpenBSD: sshconnect2.c,v 1.57 2001/03/27 17:46:49 provos Exp $");
|
||||||
|
|
||||||
#include <openssl/bn.h>
|
#include <openssl/bn.h>
|
||||||
#include <openssl/md5.h>
|
#include <openssl/md5.h>
|
||||||
|
@ -46,6 +46,7 @@ RCSID("$OpenBSD: sshconnect2.c,v 1.56 2001/03/26 08:07:09 markus Exp $");
|
||||||
#include "sshconnect.h"
|
#include "sshconnect.h"
|
||||||
#include "authfile.h"
|
#include "authfile.h"
|
||||||
#include "cli.h"
|
#include "cli.h"
|
||||||
|
#include "dh.h"
|
||||||
#include "dispatch.h"
|
#include "dispatch.h"
|
||||||
#include "authfd.h"
|
#include "authfd.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
@ -309,7 +310,7 @@ ssh_dhgex_client(Kex *kex, char *host, struct sockaddr *hostaddr,
|
||||||
int plen, dlen;
|
int plen, dlen;
|
||||||
u_int klen, kout;
|
u_int klen, kout;
|
||||||
char *signature = NULL;
|
char *signature = NULL;
|
||||||
u_int slen, nbits;
|
u_int slen, nbits, min, max;
|
||||||
char *server_host_key_blob = NULL;
|
char *server_host_key_blob = NULL;
|
||||||
Key *server_host_key;
|
Key *server_host_key;
|
||||||
u_int sbloblen;
|
u_int sbloblen;
|
||||||
|
@ -322,14 +323,31 @@ ssh_dhgex_client(Kex *kex, char *host, struct sockaddr *hostaddr,
|
||||||
|
|
||||||
nbits = dh_estimate(kex->we_need * 8);
|
nbits = dh_estimate(kex->we_need * 8);
|
||||||
|
|
||||||
debug("Sending SSH2_MSG_KEX_DH_GEX_REQUEST.");
|
if (datafellows & SSH_OLD_DHGEX) {
|
||||||
packet_start(SSH2_MSG_KEX_DH_GEX_REQUEST);
|
debug("Sending SSH2_MSG_KEX_DH_GEX_REQUEST_OLD.");
|
||||||
packet_put_int(nbits);
|
|
||||||
|
/* Old GEX request */
|
||||||
|
packet_start(SSH2_MSG_KEX_DH_GEX_REQUEST_OLD);
|
||||||
|
packet_put_int(nbits);
|
||||||
|
min = DH_GRP_MIN;
|
||||||
|
max = DH_GRP_MAX;
|
||||||
|
} else {
|
||||||
|
debug("Sending SSH2_MSG_KEX_DH_GEX_REQUEST.");
|
||||||
|
|
||||||
|
/* New GEX request */
|
||||||
|
min = DH_GRP_MIN;
|
||||||
|
max = MIN(DH_GRP_MAX, nbits * 1.25);
|
||||||
|
|
||||||
|
packet_start(SSH2_MSG_KEX_DH_GEX_REQUEST);
|
||||||
|
packet_put_int(min);
|
||||||
|
packet_put_int(nbits);
|
||||||
|
packet_put_int(max);
|
||||||
|
}
|
||||||
packet_send();
|
packet_send();
|
||||||
packet_write_wait();
|
packet_write_wait();
|
||||||
|
|
||||||
#ifdef DEBUG_KEXDH
|
#ifdef DEBUG_KEXDH
|
||||||
fprintf(stderr, "\nnbits = %d", nbits);
|
fprintf(stderr, "\nmin = %d, nbits = %d, max = %d", min, nbits, max);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
debug("Wait SSH2_MSG_KEX_DH_GEX_GROUP.");
|
debug("Wait SSH2_MSG_KEX_DH_GEX_GROUP.");
|
||||||
|
@ -344,6 +362,11 @@ ssh_dhgex_client(Kex *kex, char *host, struct sockaddr *hostaddr,
|
||||||
if ((g = BN_new()) == NULL)
|
if ((g = BN_new()) == NULL)
|
||||||
fatal("BN_new");
|
fatal("BN_new");
|
||||||
packet_get_bignum2(g, &dlen);
|
packet_get_bignum2(g, &dlen);
|
||||||
|
|
||||||
|
if (BN_num_bits(p) < min || BN_num_bits(p) > max)
|
||||||
|
fatal("DH_GEX group out of range: %d !< %d !< %d",
|
||||||
|
min, BN_num_bits(p), max);
|
||||||
|
|
||||||
dh = dh_new_group(g, p);
|
dh = dh_new_group(g, p);
|
||||||
|
|
||||||
dh_gen_key(dh, kex->we_need * 8);
|
dh_gen_key(dh, kex->we_need * 8);
|
||||||
|
|
34
sshd.c
34
sshd.c
|
@ -40,7 +40,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
RCSID("$OpenBSD: sshd.c,v 1.180 2001/03/27 10:34:08 markus Exp $");
|
RCSID("$OpenBSD: sshd.c,v 1.181 2001/03/27 17:46:49 provos Exp $");
|
||||||
|
|
||||||
#include <openssl/dh.h>
|
#include <openssl/dh.h>
|
||||||
#include <openssl/bn.h>
|
#include <openssl/bn.h>
|
||||||
|
@ -1614,7 +1614,7 @@ ssh_dhgex_server(Kex *kex, Buffer *client_kexinit, Buffer *server_kexinit)
|
||||||
int i;
|
int i;
|
||||||
#endif
|
#endif
|
||||||
int payload_len, dlen;
|
int payload_len, dlen;
|
||||||
int slen, nbits;
|
int slen, nbits, type, min, max;
|
||||||
u_char *signature = NULL;
|
u_char *signature = NULL;
|
||||||
u_char *server_host_key_blob = NULL;
|
u_char *server_host_key_blob = NULL;
|
||||||
u_int sbloblen;
|
u_int sbloblen;
|
||||||
|
@ -1632,9 +1632,33 @@ ssh_dhgex_server(Kex *kex, Buffer *client_kexinit, Buffer *server_kexinit)
|
||||||
|
|
||||||
/* KEXDHGEX */
|
/* KEXDHGEX */
|
||||||
debug("Wait SSH2_MSG_KEX_DH_GEX_REQUEST.");
|
debug("Wait SSH2_MSG_KEX_DH_GEX_REQUEST.");
|
||||||
packet_read_expect(&payload_len, SSH2_MSG_KEX_DH_GEX_REQUEST);
|
type = packet_read(&payload_len);
|
||||||
nbits = packet_get_int();
|
if (type != SSH2_MSG_KEX_DH_GEX_REQUEST_OLD &&
|
||||||
dh = choose_dh(nbits);
|
type != SSH2_MSG_KEX_DH_GEX_REQUEST)
|
||||||
|
packet_disconnect("Protocol error: expected type %d or %d, got %d",
|
||||||
|
SSH2_MSG_KEX_DH_GEX_REQUEST_OLD,
|
||||||
|
SSH2_MSG_KEX_DH_GEX_REQUEST,
|
||||||
|
type);
|
||||||
|
if (type == SSH2_MSG_KEX_DH_GEX_REQUEST_OLD) {
|
||||||
|
nbits = packet_get_int();
|
||||||
|
min = DH_GRP_MIN;
|
||||||
|
max = DH_GRP_MAX;
|
||||||
|
} else {
|
||||||
|
min = packet_get_int();
|
||||||
|
nbits = packet_get_int();
|
||||||
|
max = packet_get_int();
|
||||||
|
|
||||||
|
min = MAX(DH_GRP_MIN, min);
|
||||||
|
max = MIN(DH_GRP_MAX, max);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (max < min || nbits < min || max < nbits)
|
||||||
|
fatal("DH_GEX_REQUEST, bad parameters: %d !< %d !< %d",
|
||||||
|
min, nbits, max);
|
||||||
|
|
||||||
|
dh = choose_dh(min, nbits, max);
|
||||||
|
if (dh == NULL)
|
||||||
|
packet_disconnect("Protocol error: no matching DH grp found");
|
||||||
|
|
||||||
debug("Sending SSH2_MSG_KEX_DH_GEX_GROUP.");
|
debug("Sending SSH2_MSG_KEX_DH_GEX_GROUP.");
|
||||||
packet_start(SSH2_MSG_KEX_DH_GEX_GROUP);
|
packet_start(SSH2_MSG_KEX_DH_GEX_GROUP);
|
||||||
|
|
Loading…
Reference in New Issue