components/openssh/sources/kexgssc.c
author Jan Parcel <jan.parcel@oracle.com>
Mon, 25 Jan 2016 10:57:40 -0800
branchs11u3-sru
changeset 5324 5683175b6e99
child 7320 edeb951aa980
permissions -rw-r--r--
PSARC/2015/395 OpenSSH 7.1p1 PSARC 2014/390 OpenSSH GSSKEY 21696247 upgrade OpenSSH to 7.1p1 22031540 problem in UTILITY/OPENSSH 22022180 problem in UTILITY/OPENSSH 22048638 problem in UTILITY/OPENSSH 19775805 OpenSSH contains a redundant call to do_pam_setcred() 21379157 OpenSSH shouldn't call setproject(3PROJECT) when configured to use PAM 20919294 upgrade OpenSSH to 6.8p1 19130869 migrate the Xforwarding bug fix (15350344) from SunSSH to OpenSSH 21861322 OpenSSH client hangs on broken pipe 22018764 remove cast128-cbc from OpenSSH 21919790 add GSSKeyEx as an alias to GSSAPIKeyExchange in OpenSSH 19941148 GSS-API Key Exchange for OpenSSH 21643415 OpenSSH should use AI_ADDRCONFIG per bug 19827438 20370803 OpenSSH patch number collision 20711463 OpenSSH wants to be able to login to a role too 22389801 OpenSSH: remove cast from ssh(1), sshd(8), ssh_config(5) and sshd_config(5) 22582153 openssh system/linker should be added to core REQ
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
5324
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
     1
/*
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
     2
 * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved.
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
     3
 *
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
     4
 * Redistribution and use in source and binary forms, with or without
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
     5
 * modification, are permitted provided that the following conditions
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
     6
 * are met:
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
     7
 * 1. Redistributions of source code must retain the above copyright
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
     8
 *    notice, this list of conditions and the following disclaimer.
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
     9
 * 2. Redistributions in binary form must reproduce the above copyright
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    10
 *    notice, this list of conditions and the following disclaimer in the
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    11
 *    documentation and/or other materials provided with the distribution.
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    12
 *
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    13
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    14
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    15
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    16
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    17
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    18
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    19
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    20
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    21
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    22
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    23
 */
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    24
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    25
/*
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    26
 * May 22, 2015
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    27
 * In version 6.8 a new packet interface has been introduced to OpenSSH,
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    28
 * while the old packet API has been provided in opacket.c.
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    29
 * At this moment we are not rewritting GSS-API key exchange code to the new
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    30
 * API, just adjusting it to still work with new struct ssh.
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    31
 * Rewritting to the new API can be considered in the future.
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    32
 */
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    33
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    34
#include "includes.h"
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    35
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    36
#ifdef GSSAPI
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    37
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    38
#include "includes.h"
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    39
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    40
#include <openssl/crypto.h>
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    41
#include <openssl/bn.h>
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    42
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    43
#include <signal.h>	/* for sig_atomic_t in kex.h */
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    44
#include <string.h>
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    45
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    46
#include "xmalloc.h"
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    47
#include "buffer.h"
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    48
#include "ssh2.h"
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    49
#include "key.h"
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    50
#include "cipher.h"
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    51
#include "digest.h"
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    52
#include "kex.h"
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    53
#include "log.h"
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    54
#include "packet.h"
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    55
#include "dh.h"
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    56
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    57
#include "ssh-gss.h"
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    58
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    59
int
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    60
kexgss_client(struct ssh *ssh) {
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    61
	gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    62
	gss_buffer_desc recv_tok, gssbuf, msg_tok, *token_ptr;
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    63
	Gssctxt *ctxt;
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    64
	OM_uint32 maj_status, min_status, ret_flags;
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    65
	uint_t klen, kout, slen = 0, strlen;
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    66
	DH *dh;
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    67
	BIGNUM *dh_server_pub = NULL;
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    68
	BIGNUM *shared_secret = NULL;
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    69
	BIGNUM *p = NULL;
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    70
	BIGNUM *g = NULL;
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    71
	uchar_t *kbuf;
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    72
	uchar_t *serverhostkey = NULL;
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    73
	uchar_t *empty = "";
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    74
	char *msg;
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    75
	char *lang;
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    76
	int type = 0;
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    77
	int first = 1;
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    78
	int nbits = 0, min = DH_GRP_MIN, max = DH_GRP_MAX;
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    79
	struct kex *kex = ssh->kex;
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    80
	int r;
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    81
	uchar_t hash[SSH_DIGEST_MAX_LENGTH];
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    82
	size_t hashlen;
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    83
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    84
	/* Initialise our GSSAPI world */
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    85
	ssh_gssapi_build_ctx(&ctxt);
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    86
	if (ssh_gssapi_id_kex(ctxt, kex->name, kex->kex_type)
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    87
	    == GSS_C_NO_OID)
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    88
		fatal("Couldn't identify host exchange");
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    89
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    90
	if (ssh_gssapi_import_name(ctxt, kex->gss_host))
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    91
		fatal("Couldn't import hostname");
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    92
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    93
	switch (kex->kex_type) {
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    94
	case KEX_GSS_GRP1_SHA1:
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    95
		kex->dh = dh_new_group1();
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    96
		break;
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    97
	case KEX_GSS_GRP14_SHA1:
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    98
		kex->dh = dh_new_group14();
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
    99
		break;
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   100
	case KEX_GSS_GEX_SHA1:
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   101
		debug("Doing group exchange\n");
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   102
		nbits = dh_estimate(kex->we_need * 8);
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   103
		packet_start(SSH2_MSG_KEXGSS_GROUPREQ);
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   104
		packet_put_int(min);
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   105
		packet_put_int(nbits);
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   106
		packet_put_int(max);
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   107
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   108
		packet_send();
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   109
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   110
		packet_read_expect(SSH2_MSG_KEXGSS_GROUP);
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   111
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   112
		if ((p = BN_new()) == NULL)
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   113
			fatal("BN_new() failed");
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   114
		packet_get_bignum2(p);
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   115
		if ((g = BN_new()) == NULL)
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   116
			fatal("BN_new() failed");
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   117
		packet_get_bignum2(g);
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   118
		packet_check_eom();
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   119
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   120
		if (BN_num_bits(p) < min || BN_num_bits(p) > max)
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   121
			fatal("GSSGRP_GEX group out of range: %d !< %d !< %d",
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   122
			    min, BN_num_bits(p), max);
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   123
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   124
		kex->dh = dh_new_group(g, p);
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   125
		break;
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   126
	default:
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   127
		fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type);
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   128
	}
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   129
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   130
	/* Step 1 - e is dh->pub_key */
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   131
	dh_gen_key(kex->dh, kex->we_need * 8);
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   132
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   133
	/* This is f, we initialise it now to make life easier */
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   134
	dh_server_pub = BN_new();
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   135
	if (dh_server_pub == NULL)
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   136
		fatal("dh_server_pub == NULL");
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   137
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   138
	token_ptr = GSS_C_NO_BUFFER;
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   139
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   140
	do {
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   141
		debug("Calling gss_init_sec_context");
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   142
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   143
		maj_status = ssh_gssapi_init_ctx(ctxt,
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   144
		    kex->gss_deleg_creds, token_ptr, &send_tok,
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   145
		    &ret_flags);
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   146
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   147
		if (GSS_ERROR(maj_status)) {
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   148
			if (send_tok.length != 0) {
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   149
				packet_start(SSH2_MSG_KEXGSS_CONTINUE);
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   150
				packet_put_string(send_tok.value,
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   151
				    send_tok.length);
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   152
			}
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   153
			fatal("gss_init_context failed");
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   154
		}
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   155
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   156
		/* If we've got an old receive buffer get rid of it */
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   157
		if (token_ptr != GSS_C_NO_BUFFER)
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   158
			free(recv_tok.value);
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   159
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   160
		if (maj_status == GSS_S_COMPLETE) {
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   161
			/* If mutual state flag is not true, kex fails */
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   162
			if (!(ret_flags & GSS_C_MUTUAL_FLAG))
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   163
				fatal("Mutual authentication failed");
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   164
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   165
			/* If integ avail flag is not true kex fails */
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   166
			if (!(ret_flags & GSS_C_INTEG_FLAG))
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   167
				fatal("Integrity check failed");
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   168
		}
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   169
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   170
		/*
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   171
		 * If we have data to send, then the last message that we
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   172
		 * received cannot have been a 'complete'.
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   173
		 */
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   174
		if (send_tok.length != 0) {
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   175
			if (first) {
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   176
				packet_start(SSH2_MSG_KEXGSS_INIT);
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   177
				packet_put_string(send_tok.value,
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   178
				    send_tok.length);
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   179
				packet_put_bignum2(kex->dh->pub_key);
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   180
				first = 0;
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   181
			} else {
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   182
				packet_start(SSH2_MSG_KEXGSS_CONTINUE);
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   183
				packet_put_string(send_tok.value,
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   184
				    send_tok.length);
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   185
			}
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   186
			packet_send();
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   187
			gss_release_buffer(&min_status, &send_tok);
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   188
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   189
			/* If we've sent them data, they should reply */
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   190
			do {
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   191
				type = packet_read();
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   192
				if (type == SSH2_MSG_KEXGSS_HOSTKEY) {
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   193
					debug("Received KEXGSS_HOSTKEY");
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   194
					if (serverhostkey)
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   195
						fatal("Server host key received"
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   196
						    "more than once");
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   197
					serverhostkey =
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   198
					    packet_get_string(&slen);
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   199
				}
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   200
			} while (type == SSH2_MSG_KEXGSS_HOSTKEY);
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   201
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   202
			switch (type) {
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   203
			case SSH2_MSG_KEXGSS_CONTINUE:
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   204
				debug("Received GSSAPI_CONTINUE");
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   205
				if (maj_status == GSS_S_COMPLETE)
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   206
					fatal("GSSAPI Continue received from"
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   207
					    "server when complete");
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   208
				recv_tok.value = packet_get_string(&strlen);
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   209
				recv_tok.length = strlen;
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   210
				break;
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   211
			case SSH2_MSG_KEXGSS_COMPLETE:
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   212
				debug("Received GSSAPI_COMPLETE");
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   213
				packet_get_bignum2(dh_server_pub);
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   214
				msg_tok.value =  packet_get_string(&strlen);
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   215
				msg_tok.length = strlen;
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   216
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   217
				/* Is there a token included? */
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   218
				if (packet_get_char()) {
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   219
					recv_tok.value=
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   220
					    packet_get_string(&strlen);
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   221
					recv_tok.length = strlen;
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   222
					/* If complete - protocol error */
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   223
					if (maj_status == GSS_S_COMPLETE)
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   224
						packet_disconnect("Protocol"
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   225
						    " error: received token"
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   226
						    " when complete");
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   227
				} else {
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   228
					/* No token included */
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   229
					if (maj_status != GSS_S_COMPLETE)
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   230
						packet_disconnect("Protocol"
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   231
						    " error: did not receive"
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   232
						    " final token");
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   233
				}
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   234
				break;
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   235
			case SSH2_MSG_KEXGSS_ERROR:
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   236
				debug("Received Error");
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   237
				maj_status = packet_get_int();
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   238
				min_status = packet_get_int();
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   239
				msg = packet_get_string(NULL);
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   240
				lang = packet_get_string(NULL);
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   241
				fatal("GSSAPI Error: \n%.400s", msg);
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   242
			default:
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   243
				packet_disconnect("Protocol error: didn't"
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   244
				    " expect packet type %d", type);
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   245
			}
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   246
			token_ptr = &recv_tok;
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   247
		} else {
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   248
			/* No data, and not complete */
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   249
			if (maj_status != GSS_S_COMPLETE)
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   250
				fatal("Not complete, and no token output");
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   251
		}
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   252
	} while (maj_status & GSS_S_CONTINUE_NEEDED);
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   253
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   254
	/*
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   255
	 * We _must_ have received a COMPLETE message in reply from the
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   256
	 * server, which will have set dh_server_pub and msg_tok
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   257
	 */
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   258
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   259
	if (type != SSH2_MSG_KEXGSS_COMPLETE)
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   260
		fatal("Didn't receive SSH2_MSG_KEXGSS_COMPLETE when expected");
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   261
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   262
	/* Check f in range [1, p-1] */
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   263
	if (!dh_pub_is_valid(kex->dh, dh_server_pub))
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   264
		packet_disconnect("bad server public DH value");
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   265
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   266
	/* compute K=f^x mod p */
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   267
	klen = DH_size(kex->dh);
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   268
	kbuf = xmalloc(klen);
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   269
	kout = DH_compute_key(kbuf, dh_server_pub, kex->dh);
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   270
	if (kout < 0)
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   271
		fatal("DH_compute_key: failed");
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   272
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   273
	shared_secret = BN_new();
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   274
	if (shared_secret == NULL)
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   275
		fatal("kexgss_client: BN_new failed");
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   276
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   277
	if (BN_bin2bn(kbuf, kout, shared_secret) == NULL)
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   278
		fatal("kexdh_client: BN_bin2bn failed");
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   279
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   280
	memset(kbuf, 0, klen);
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   281
	free(kbuf);
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   282
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   283
	hashlen = sizeof (hash);
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   284
	switch (kex->kex_type) {
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   285
	case KEX_GSS_GRP1_SHA1:
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   286
	case KEX_GSS_GRP14_SHA1:
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   287
		kex_dh_hash(kex->client_version_string,
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   288
		    kex->server_version_string,
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   289
		    buffer_ptr(kex->my), buffer_len(kex->my),
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   290
		    buffer_ptr(kex->peer), buffer_len(kex->peer),
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   291
		    (serverhostkey ? serverhostkey : empty), slen,
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   292
		    kex->dh->pub_key,	/* e */
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   293
		    dh_server_pub,	/* f */
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   294
		    shared_secret,	/* K */
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   295
		    hash, &hashlen);
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   296
		break;
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   297
	case KEX_GSS_GEX_SHA1:
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   298
		kexgex_hash(
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   299
		    kex->hash_alg,
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   300
		    kex->client_version_string,
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   301
		    kex->server_version_string,
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   302
		    buffer_ptr(kex->my), buffer_len(kex->my),
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   303
		    buffer_ptr(kex->peer), buffer_len(kex->peer),
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   304
		    (serverhostkey ? serverhostkey : empty), slen,
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   305
		    min, nbits, max,
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   306
		    kex->dh->p, kex->dh->g,
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   307
		    kex->dh->pub_key,
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   308
		    dh_server_pub,
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   309
		    shared_secret,
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   310
		    hash, &hashlen);
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   311
		break;
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   312
	default:
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   313
		fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type);
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   314
	}
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   315
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   316
	gssbuf.value = hash;
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   317
	gssbuf.length = hashlen;
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   318
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   319
	/* Verify that the hash matches the MIC we just got. */
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   320
	if (GSS_ERROR(ssh_gssapi_checkmic(ctxt, &gssbuf, &msg_tok)))
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   321
		packet_disconnect("Hash's MIC didn't verify");
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   322
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   323
	free(msg_tok.value);
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   324
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   325
	DH_free(kex->dh);
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   326
	if (serverhostkey)
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   327
		free(serverhostkey);
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   328
	BN_clear_free(dh_server_pub);
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   329
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   330
	/* save session id */
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   331
	if (kex->session_id == NULL) {
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   332
		kex->session_id_len = hashlen;
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   333
		kex->session_id = xmalloc(kex->session_id_len);
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   334
		memcpy(kex->session_id, hash, kex->session_id_len);
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   335
	}
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   336
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   337
	if (gss_kex_context == NULL)
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   338
		gss_kex_context = ctxt;
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   339
	else
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   340
		ssh_gssapi_delete_ctx(&ctxt);
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   341
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   342
	if ((r = kex_derive_keys_bn(ssh, hash, hashlen, shared_secret)) == 0)
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   343
		r = kex_send_newkeys(ssh);
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   344
	return (r);
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   345
}
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   346
5683175b6e99 PSARC/2015/395 OpenSSH 7.1p1
Jan Parcel <jan.parcel@oracle.com>
parents:
diff changeset
   347
#endif /* GSSAPI */