components/openssh/sources/kexgsss.c
changeset 4503 bf30d46ab06e
parent 3574 80e9a4e240d3
child 6030 494adc5697ee
equal deleted inserted replaced
4498:ce7fc2376fb0 4503:bf30d46ab06e
    20  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    20  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    21  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
    21  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
    22  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    22  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    23  */
    23  */
    24 
    24 
       
    25 /*
       
    26  * May 22, 2015
       
    27  * In version 6.8 a new packet interface has been introduced to OpenSSH,
       
    28  * while the old packet API has been provided in opacket.c.
       
    29  * At this moment we are not rewritting GSS-API key exchange code to the new
       
    30  * API, just adjusting it to still work with new struct ssh.
       
    31  * Rewritting to the new API can be considered in the future.
       
    32  */
       
    33 
    25 #include "includes.h"
    34 #include "includes.h"
    26 
    35 
    27 #ifdef GSSAPI
    36 #ifdef GSSAPI
    28 
    37 
       
    38 #include <signal.h>	/* for sig_atomic_t in kex.h */
    29 #include <string.h>
    39 #include <string.h>
    30 
    40 
    31 #include <openssl/crypto.h>
    41 #include <openssl/crypto.h>
    32 #include <openssl/bn.h>
    42 #include <openssl/bn.h>
    33 
    43 
    34 #include "xmalloc.h"
    44 #include "xmalloc.h"
    35 #include "buffer.h"
    45 #include "buffer.h"
    36 #include "ssh2.h"
    46 #include "ssh2.h"
    37 #include "key.h"
    47 #include "key.h"
    38 #include "cipher.h"
    48 #include "cipher.h"
       
    49 #include "digest.h"
    39 #include "kex.h"
    50 #include "kex.h"
    40 #include "log.h"
    51 #include "log.h"
    41 #include "packet.h"
    52 #include "packet.h"
    42 #include "dh.h"
    53 #include "dh.h"
    43 #include "ssh-gss.h"
    54 #include "ssh-gss.h"
    44 #include "monitor_wrap.h"
    55 #include "monitor_wrap.h"
    45 
    56 
    46 void
    57 int
    47 kexgss_server(Kex *kex)
    58 kexgss_server(struct ssh *ssh)
    48 {
    59 {
    49 	OM_uint32 maj_status, min_status;
    60 	OM_uint32 maj_status, min_status;
    50 
    61 
    51 	/*
    62 	/*
    52 	 * Some GSSAPI implementations use the input value of ret_flags (an
    63 	 * Some GSSAPI implementations use the input value of ret_flags (an
    57 
    68 
    58 	OM_uint32 ret_flags = 0;
    69 	OM_uint32 ret_flags = 0;
    59 	gss_buffer_desc gssbuf, recv_tok, msg_tok;
    70 	gss_buffer_desc gssbuf, recv_tok, msg_tok;
    60 	gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
    71 	gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
    61 	Gssctxt *ctxt = NULL;
    72 	Gssctxt *ctxt = NULL;
    62 	uint_t slen, klen, kout, hashlen;
    73 	uint_t slen, klen, kout;
    63 	uchar_t *kbuf, *hash;
    74 	uchar_t *kbuf;
    64 	DH *dh;
    75 	DH *dh;
    65 	int min = -1, max = -1, nbits = -1;
    76 	int min = -1, max = -1, nbits = -1;
    66 	BIGNUM *shared_secret = NULL;
    77 	BIGNUM *shared_secret = NULL;
    67 	BIGNUM *dh_client_pub = NULL;
    78 	BIGNUM *dh_client_pub = NULL;
    68 	int type = 0;
    79 	int type = 0;
    69 	gss_OID oid;
    80 	gss_OID oid;
    70 	char *mechs;
    81 	char *mechs;
       
    82 	struct kex *kex = ssh->kex;
       
    83 	int r;
       
    84 	uchar_t hash[SSH_DIGEST_MAX_LENGTH];
       
    85 	size_t hashlen;
    71 
    86 
    72 	/* Initialise GSSAPI */
    87 	/* Initialise GSSAPI */
    73 
    88 
    74 	/*
    89 	/*
    75 	 * If we're rekeying, privsep means that some of the private structures
    90 	 * If we're rekeying, privsep means that some of the private structures
    90 	if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt, oid))))
   105 	if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt, oid))))
    91 		fatal("Unable to acquire credentials for the server");
   106 		fatal("Unable to acquire credentials for the server");
    92 
   107 
    93 	switch (kex->kex_type) {
   108 	switch (kex->kex_type) {
    94 	case KEX_GSS_GRP1_SHA1:
   109 	case KEX_GSS_GRP1_SHA1:
    95 		dh = dh_new_group1();
   110 		kex->dh = dh_new_group1();
    96 		break;
   111 		break;
    97 	case KEX_GSS_GRP14_SHA1:
   112 	case KEX_GSS_GRP14_SHA1:
    98 		dh = dh_new_group14();
   113 		kex->dh = dh_new_group14();
    99 		break;
   114 		break;
   100 	case KEX_GSS_GEX_SHA1:
   115 	case KEX_GSS_GEX_SHA1:
   101 		debug("Doing group exchange");
   116 		debug("Doing group exchange");
   102 		packet_read_expect(SSH2_MSG_KEXGSS_GROUPREQ);
   117 		packet_read_expect(SSH2_MSG_KEXGSS_GROUPREQ);
   103 		min = packet_get_int();
   118 		min = packet_get_int();
   107 		max = MIN(DH_GRP_MAX, max);
   122 		max = MIN(DH_GRP_MAX, max);
   108 		packet_check_eom();
   123 		packet_check_eom();
   109 		if (max < min || nbits < min || max < nbits)
   124 		if (max < min || nbits < min || max < nbits)
   110 			fatal("GSS_GEX, bad parameters: %d !< %d !< %d",
   125 			fatal("GSS_GEX, bad parameters: %d !< %d !< %d",
   111 			    min, nbits, max);
   126 			    min, nbits, max);
   112 		dh = PRIVSEP(choose_dh(min, nbits, max));
   127 		kex->dh = PRIVSEP(choose_dh(min, nbits, max));
   113 		if (dh == NULL)
   128 		if (kex->dh == NULL)
   114 			packet_disconnect("Protocol error:"
   129 			packet_disconnect("Protocol error:"
   115 			    " no matching group found");
   130 			    " no matching group found");
   116 
   131 
   117 		packet_start(SSH2_MSG_KEXGSS_GROUP);
   132 		packet_start(SSH2_MSG_KEXGSS_GROUP);
   118 		packet_put_bignum2(dh->p);
   133 		packet_put_bignum2(kex->dh->p);
   119 		packet_put_bignum2(dh->g);
   134 		packet_put_bignum2(kex->dh->g);
   120 		packet_send();
   135 		packet_send();
   121 
   136 
   122 		packet_write_wait();
   137 		packet_write_wait();
   123 		break;
   138 		break;
   124 	default:
   139 	default:
   125 		fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type);
   140 		fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type);
   126 	}
   141 	}
   127 
   142 
   128 	dh_gen_key(dh, kex->we_need * 8);
   143 	dh_gen_key(kex->dh, kex->we_need * 8);
   129 
   144 
   130 	do {
   145 	do {
   131 		debug("Wait SSH2_MSG_GSSAPI_INIT");
   146 		debug("Wait SSH2_MSG_GSSAPI_INIT");
   132 		type = packet_read();
   147 		type = packet_read();
   133 		switch (type) {
   148 		switch (type) {
   188 		fatal("Mutual Authentication flag wasn't set");
   203 		fatal("Mutual Authentication flag wasn't set");
   189 
   204 
   190 	if (!(ret_flags & GSS_C_INTEG_FLAG))
   205 	if (!(ret_flags & GSS_C_INTEG_FLAG))
   191 		fatal("Integrity flag wasn't set");
   206 		fatal("Integrity flag wasn't set");
   192 
   207 
   193 	if (!dh_pub_is_valid(dh, dh_client_pub))
   208 	if (!dh_pub_is_valid(kex->dh, dh_client_pub))
   194 		packet_disconnect("bad client public DH value");
   209 		packet_disconnect("bad client public DH value");
   195 
   210 
   196 	klen = DH_size(dh);
   211 	klen = DH_size(kex->dh);
   197 	kbuf = xmalloc(klen);
   212 	kbuf = xmalloc(klen);
   198 	kout = DH_compute_key(kbuf, dh_client_pub, dh);
   213 	kout = DH_compute_key(kbuf, dh_client_pub, kex->dh);
   199 	if (kout < 0)
   214 	if (kout < 0)
   200 		fatal("DH_compute_key: failed");
   215 		fatal("DH_compute_key: failed");
   201 
   216 
   202 	shared_secret = BN_new();
   217 	shared_secret = BN_new();
   203 	if (shared_secret == NULL)
   218 	if (shared_secret == NULL)
   207 		fatal("kexgss_server: BN_bin2bn failed");
   222 		fatal("kexgss_server: BN_bin2bn failed");
   208 
   223 
   209 	memset(kbuf, 0, klen);
   224 	memset(kbuf, 0, klen);
   210 	free(kbuf);
   225 	free(kbuf);
   211 
   226 
       
   227 	hashlen = sizeof (hash);
   212 	switch (kex->kex_type) {
   228 	switch (kex->kex_type) {
   213 	case KEX_GSS_GRP1_SHA1:
   229 	case KEX_GSS_GRP1_SHA1:
   214 	case KEX_GSS_GRP14_SHA1:
   230 	case KEX_GSS_GRP14_SHA1:
   215 		kex_dh_hash(
   231 		kex_dh_hash(
   216 		    kex->client_version_string, kex->server_version_string,
   232 		    kex->client_version_string, kex->server_version_string,
   217 		    buffer_ptr(&kex->peer), buffer_len(&kex->peer),
   233 		    buffer_ptr(kex->peer), buffer_len(kex->peer),
   218 		    buffer_ptr(&kex->my), buffer_len(&kex->my),
   234 		    buffer_ptr(kex->my), buffer_len(kex->my),
   219 		    NULL, 0, /* Change this if we start sending host keys */
   235 		    NULL, 0, /* Change this if we start sending host keys */
   220 		    dh_client_pub, dh->pub_key, shared_secret,
   236 		    dh_client_pub, kex->dh->pub_key, shared_secret,
   221 		    &hash, &hashlen);
   237 		    hash, &hashlen);
   222 		break;
   238 		break;
   223 	case KEX_GSS_GEX_SHA1:
   239 	case KEX_GSS_GEX_SHA1:
   224 		kexgex_hash(
   240 		kexgex_hash(
   225 		    kex->hash_alg,
   241 		    kex->hash_alg,
   226 		    kex->client_version_string, kex->server_version_string,
   242 		    kex->client_version_string, kex->server_version_string,
   227 		    buffer_ptr(&kex->peer), buffer_len(&kex->peer),
   243 		    buffer_ptr(kex->peer), buffer_len(kex->peer),
   228 		    buffer_ptr(&kex->my), buffer_len(&kex->my),
   244 		    buffer_ptr(kex->my), buffer_len(kex->my),
   229 		    NULL, 0,
   245 		    NULL, 0,
   230 		    min, nbits, max,
   246 		    min, nbits, max,
   231 		    dh->p, dh->g,
   247 		    kex->dh->p, kex->dh->g,
   232 		    dh_client_pub,
   248 		    dh_client_pub,
   233 		    dh->pub_key,
   249 		    kex->dh->pub_key,
   234 		    shared_secret,
   250 		    shared_secret,
   235 		    &hash, &hashlen);
   251 		    hash, &hashlen);
   236 		break;
   252 		break;
   237 	default:
   253 	default:
   238 		fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type);
   254 		fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type);
   239 	}
   255 	}
   240 
   256 
   251 
   267 
   252 	if (GSS_ERROR(PRIVSEP(ssh_gssapi_sign(ctxt, &gssbuf, &msg_tok))))
   268 	if (GSS_ERROR(PRIVSEP(ssh_gssapi_sign(ctxt, &gssbuf, &msg_tok))))
   253 		fatal("Couldn't get MIC");
   269 		fatal("Couldn't get MIC");
   254 
   270 
   255 	packet_start(SSH2_MSG_KEXGSS_COMPLETE);
   271 	packet_start(SSH2_MSG_KEXGSS_COMPLETE);
   256 	packet_put_bignum2(dh->pub_key);
   272 	packet_put_bignum2(kex->dh->pub_key);
   257 	packet_put_string(msg_tok.value, msg_tok.length);
   273 	packet_put_string(msg_tok.value, msg_tok.length);
   258 
   274 
   259 	if (send_tok.length != 0) {
   275 	if (send_tok.length != 0) {
   260 		packet_put_char(1); /* true */
   276 		packet_put_char(1); /* true */
   261 		packet_put_string(send_tok.value, send_tok.length);
   277 		packet_put_string(send_tok.value, send_tok.length);
   270 	if (gss_kex_context == NULL)
   286 	if (gss_kex_context == NULL)
   271 		gss_kex_context = ctxt;
   287 		gss_kex_context = ctxt;
   272 	else
   288 	else
   273 		ssh_gssapi_delete_ctx(&ctxt);
   289 		ssh_gssapi_delete_ctx(&ctxt);
   274 
   290 
   275 	DH_free(dh);
   291 	DH_free(kex->dh);
   276 
   292 
   277 	kex_derive_keys_bn(kex, hash, hashlen, shared_secret);
   293 	if ((r = kex_derive_keys_bn(ssh, hash, hashlen, shared_secret)) == 0)
   278 	BN_clear_free(shared_secret);
   294 		r = kex_send_newkeys(ssh);
   279 	kex_finish(kex);
   295 	return (r);
   280 }
   296 }
   281 #endif /* GSSAPI */
   297 #endif /* GSSAPI */