/* $OpenBSD: auth2-jpake.c,v 1.4 2010/08/31 11:54:45 djm Exp $ */
/*
 * Copyright (c) 2008 Damien Miller.  All rights reserved.
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

/*
 * Server side of zero-knowledge password auth using J-PAKE protocol
 * as described in:
 *
 * F. Hao, P. Ryan, "Password Authenticated Key Exchange by Juggling",
 * 16th Workshop on Security Protocols, Cambridge, April 2008
 *
 * http://grouper.ieee.org/groups/1363/Research/contributions/hao-ryan-2008.pdf
 */

#ifdef JPAKE

#include <sys/types.h>
#include <sys/param.h>

#include <pwd.h>
#include <stdio.h>
#include <string.h>
#include <login_cap.h>

#include <openssl/bn.h>
#include <openssl/evp.h>

#include "xmalloc.h"
#include "ssh2.h"
#include "key.h"
#include "hostfile.h"
#include "auth.h"
#include "buffer.h"
#include "packet.h"
#include "dispatch.h"
#include "log.h"
#include "servconf.h"
#include "auth-options.h"
#include "canohost.h"
#ifdef GSSAPI
#include "ssh-gss.h"
#endif
#include "monitor_wrap.h"

#include "schnorr.h"
#include "jpake.h"

/*
 * XXX options->permit_empty_passwd (at the moment, they will be refused
 * anyway because they will mismatch on fake salt.
 */

/* Dispatch handlers */
static void input_userauth_jpake_client_step1(int, u_int32_t, void *);
static void input_userauth_jpake_client_step2(int, u_int32_t, void *);
static void input_userauth_jpake_client_confirm(int, u_int32_t, void *);

static int auth2_jpake_start(Authctxt *);

/* import */
extern ServerOptions options;
extern u_char *session_id2;
extern u_int session_id2_len;

/*
 * Attempt J-PAKE authentication.
 */
static int
userauth_jpake(Authctxt *authctxt)
{
	int authenticated = 0;

	packet_check_eom();

	debug("jpake-01@openssh.com requested");

	if (authctxt->user != NULL) {
		if (authctxt->jpake_ctx == NULL)
			authctxt->jpake_ctx = jpake_new();
		if (options.zero_knowledge_password_authentication)
			authenticated = auth2_jpake_start(authctxt);
	}

	return authenticated;
}

Authmethod method_jpake = {
	"jpake-01@openssh.com",
	userauth_jpake,
	&options.zero_knowledge_password_authentication
};

/* Clear context and callbacks */
void
auth2_jpake_stop(Authctxt *authctxt)
{
	/* unregister callbacks */
	dispatch_set(SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP1, NULL);
	dispatch_set(SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP2, NULL);
	dispatch_set(SSH2_MSG_USERAUTH_JPAKE_CLIENT_CONFIRM, NULL);
	if (authctxt->jpake_ctx != NULL) {
		jpake_free(authctxt->jpake_ctx);
		authctxt->jpake_ctx = NULL;
	}
}

/* Returns 1 if 'c' is a valid crypt(3) salt character, 0 otherwise */
static int
valid_crypt_salt(int c)
{
	if (c >= 'A' && c <= 'Z')
		return 1;
	if (c >= 'a' && c <= 'z')
		return 1;
	if (c >= '.' && c <= '9')
		return 1;
	return 0;
}

/*
 * Derive fake salt as H(username || first_private_host_key)
 * This provides relatively stable fake salts for non-existent
 * users and avoids the jpake method becoming an account validity
 * oracle.
 */
static void
derive_rawsalt(const char *username, u_char *rawsalt, u_int len)
{
	u_char *digest;
	u_int digest_len;
	Buffer b;
	Key *k;

	buffer_init(&b);
	buffer_put_cstring(&b, username);
	if ((k = get_hostkey_by_index(0)) == NULL ||
	    (k->flags & KEY_FLAG_EXT))
		fatal("%s: no hostkeys", __func__);
	switch (k->type) {
	case KEY_RSA1:
	case KEY_RSA:
		if (k->rsa->p == NULL || k->rsa->q == NULL)
			fatal("%s: RSA key missing p and/or q", __func__);
		buffer_put_bignum2(&b, k->rsa->p);
		buffer_put_bignum2(&b, k->rsa->q);
		break;
	case KEY_DSA:
		if (k->dsa->priv_key == NULL)
			fatal("%s: DSA key missing priv_key", __func__);
		buffer_put_bignum2(&b, k->dsa->priv_key);
		break;
	case KEY_ECDSA:
		if (EC_KEY_get0_private_key(k->ecdsa) == NULL)
			fatal("%s: ECDSA key missing priv_key", __func__);
		buffer_put_bignum2(&b, EC_KEY_get0_private_key(k->ecdsa));
		break;
	default:
		fatal("%s: unknown key type %d", __func__, k->type);
	}
	if (hash_buffer(buffer_ptr(&b), buffer_len(&b), EVP_sha256(),
	    &digest, &digest_len) != 0)
		fatal("%s: hash_buffer", __func__);
	buffer_free(&b);
	if (len > digest_len)
		fatal("%s: not enough bytes for rawsalt (want %u have %u)",
		    __func__, len, digest_len);
	memcpy(rawsalt, digest, len);
	bzero(digest, digest_len);
	xfree(digest);
}

/* ASCII an integer [0, 64) for inclusion in a password/salt */
static char
pw_encode64(u_int i64)
{
	const u_char e64[] =
	    "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
	return e64[i64 % 64];
}

/* Generate ASCII salt bytes for user */
static char *
makesalt(u_int want, const char *user)
{
	u_char rawsalt[32];
	static char ret[33];
	u_int i;

	if (want > sizeof(ret) - 1)
		fatal("%s: want %u", __func__, want);

	derive_rawsalt(user, rawsalt, sizeof(rawsalt));
	bzero(ret, sizeof(ret));
	for (i = 0; i < want; i++)
		ret[i] = pw_encode64(rawsalt[i]);
	bzero(rawsalt, sizeof(rawsalt));

	return ret;
}

/*
 * Select the system's default password hashing scheme and generate
 * a stable fake salt under it for use by a non-existent account.
 * Prevents jpake method being used to infer the validity of accounts.
 */
static void
fake_salt_and_scheme(Authctxt *authctxt, char **salt, char **scheme)
{
	char *rounds_s, *style;
	long long rounds;
	login_cap_t *lc;


	if ((lc = login_getclass(authctxt->pw->pw_class)) == NULL &&
	    (lc = login_getclass(NULL)) == NULL)
		fatal("%s: login_getclass failed", __func__);
	style = login_getcapstr(lc, "localcipher", NULL, NULL);
	if (style == NULL)
		style = xstrdup("blowfish,6");
	login_close(lc);
	
	if ((rounds_s = strchr(style, ',')) != NULL)
		*rounds_s++ = '\0';
	rounds = strtonum(rounds_s, 1, 1<<31, NULL);
	
	if (strcmp(style, "md5") == 0) {
		xasprintf(salt, "$1$%s$", makesalt(8, authctxt->user));
		*scheme = xstrdup("md5");
	} else if (strcmp(style, "old") == 0) {
		*salt = xstrdup(makesalt(2, authctxt->user));
		*scheme = xstrdup("crypt");
	} else if (strcmp(style, "newsalt") == 0) {
		rounds = MAX(rounds, 7250);
		rounds = MIN(rounds, (1<<24) - 1);
		xasprintf(salt, "_%c%c%c%c%s",
		    pw_encode64(rounds), pw_encode64(rounds >> 6),
		    pw_encode64(rounds >> 12), pw_encode64(rounds >> 18),
		    makesalt(4, authctxt->user));
		*scheme = xstrdup("crypt-extended");
	} else {
		/* Default to blowfish */
		rounds = MAX(rounds, 3);
		rounds = MIN(rounds, 31);
		xasprintf(salt, "$2a$%02lld$%s", rounds,
		    makesalt(22, authctxt->user));
		*scheme = xstrdup("bcrypt");
	}
	xfree(style);
	debug3("%s: fake %s salt for user %s: %s",
	    __func__, *scheme, authctxt->user, *salt);
}

/*
 * Fetch password hashing scheme, password salt and derive shared secret
 * for user. If user does not exist, a fake but stable and user-unique
 * salt will be returned.
 */
void
auth2_jpake_get_pwdata(Authctxt *authctxt, BIGNUM **s,
    char **hash_scheme, char **salt)
{
	char *cp;
	u_char *secret;
	u_int secret_len, salt_len;

#ifdef JPAKE_DEBUG
	debug3("%s: valid %d pw %.5s...", __func__,
	    authctxt->valid, authctxt->pw->pw_passwd);
#endif

	*salt = NULL;
	*hash_scheme = NULL;
	if (authctxt->valid) {
		if (strncmp(authctxt->pw->pw_passwd, "$2$", 3) == 0 &&
		    strlen(authctxt->pw->pw_passwd) > 28) {
			/*
			 * old-variant bcrypt:
			 *     "$2$", 2 digit rounds, "$", 22 bytes salt
			 */
			salt_len = 3 + 2 + 1 + 22 + 1;
			*salt = xmalloc(salt_len);
			strlcpy(*salt, authctxt->pw->pw_passwd, salt_len);
			*hash_scheme = xstrdup("bcrypt");
		} else if (strncmp(authctxt->pw->pw_passwd, "$2a$", 4) == 0 &&
		    strlen(authctxt->pw->pw_passwd) > 29) {
			/*
			 * current-variant bcrypt:
			 *     "$2a$", 2 digit rounds, "$", 22 bytes salt
			 */
			salt_len = 4 + 2 + 1 + 22 + 1;
			*salt = xmalloc(salt_len);
			strlcpy(*salt, authctxt->pw->pw_passwd, salt_len);
			*hash_scheme = xstrdup("bcrypt");
		} else if (strncmp(authctxt->pw->pw_passwd, "$1$", 3) == 0 &&
		    strlen(authctxt->pw->pw_passwd) > 5) {
			/*
			 * md5crypt:
			 *     "$1$", salt until "$"
			 */
			cp = strchr(authctxt->pw->pw_passwd + 3, '$');
			if (cp != NULL) {
				salt_len = (cp - authctxt->pw->pw_passwd) + 1;
				*salt = xmalloc(salt_len);
				strlcpy(*salt, authctxt->pw->pw_passwd,
				    salt_len);
				*hash_scheme = xstrdup("md5crypt");
			}
		} else if (strncmp(authctxt->pw->pw_passwd, "_", 1) == 0 &&
		    strlen(authctxt->pw->pw_passwd) > 9) {
			/*
			 * BSDI extended crypt:
			 *     "_", 4 digits count, 4 chars salt
			 */
			salt_len = 1 + 4 + 4 + 1;
			*salt = xmalloc(salt_len);
			strlcpy(*salt, authctxt->pw->pw_passwd, salt_len);
			*hash_scheme = xstrdup("crypt-extended");
		} else if (strlen(authctxt->pw->pw_passwd) == 13  &&
		    valid_crypt_salt(authctxt->pw->pw_passwd[0]) &&
		    valid_crypt_salt(authctxt->pw->pw_passwd[1])) {
			/*
			 * traditional crypt:
			 *     2 chars salt
			 */
			salt_len = 2 + 1;
			*salt = xmalloc(salt_len);
			strlcpy(*salt, authctxt->pw->pw_passwd, salt_len);
			*hash_scheme = xstrdup("crypt");
		}
		if (*salt == NULL) {
			debug("%s: unrecognised crypt scheme for user %s",
			    __func__, authctxt->pw->pw_name);
		}
	}
	if (*salt == NULL)
		fake_salt_and_scheme(authctxt, salt, hash_scheme);

	if (hash_buffer(authctxt->pw->pw_passwd,
	    strlen(authctxt->pw->pw_passwd), EVP_sha256(),
	    &secret, &secret_len) != 0)
		fatal("%s: hash_buffer", __func__);
	if ((*s = BN_bin2bn(secret, secret_len, NULL)) == NULL)
		fatal("%s: BN_bin2bn (secret)", __func__);
#ifdef JPAKE_DEBUG
	debug3("%s: salt = %s (len %u)", __func__,
	    *salt, (u_int)strlen(*salt));
	debug3("%s: scheme = %s", __func__, *hash_scheme);
	JPAKE_DEBUG_BN((*s, "%s: s = ", __func__));
#endif
	bzero(secret, secret_len);
	xfree(secret);
}

/*
 * Begin authentication attempt.
 * Note, sets authctxt->postponed while in subprotocol
 */
static int
auth2_jpake_start(Authctxt *authctxt)
{
	struct jpake_ctx *pctx = authctxt->jpake_ctx;
	u_char *x3_proof, *x4_proof;
	u_int x3_proof_len, x4_proof_len;
	char *salt, *hash_scheme;

	debug("%s: start", __func__);

	PRIVSEP(jpake_step1(pctx->grp,
	    &pctx->server_id, &pctx->server_id_len,
	    &pctx->x3, &pctx->x4, &pctx->g_x3, &pctx->g_x4,
	    &x3_proof, &x3_proof_len,
	    &x4_proof, &x4_proof_len));

	PRIVSEP(auth2_jpake_get_pwdata(authctxt, &pctx->s,
	    &hash_scheme, &salt));

	if (!use_privsep)
		JPAKE_DEBUG_CTX((pctx, "step 1 sending in %s", __func__));

	packet_start(SSH2_MSG_USERAUTH_JPAKE_SERVER_STEP1);
	packet_put_cstring(hash_scheme);
	packet_put_cstring(salt);
	packet_put_string(pctx->server_id, pctx->server_id_len);
	packet_put_bignum2(pctx->g_x3);
	packet_put_bignum2(pctx->g_x4);
	packet_put_string(x3_proof, x3_proof_len);
	packet_put_string(x4_proof, x4_proof_len);
	packet_send();
	packet_write_wait();

	bzero(hash_scheme, strlen(hash_scheme));
	bzero(salt, strlen(salt));
	xfree(hash_scheme);
	xfree(salt);
	bzero(x3_proof, x3_proof_len);
	bzero(x4_proof, x4_proof_len);
	xfree(x3_proof);
	xfree(x4_proof);

	/* Expect step 1 packet from peer */
	dispatch_set(SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP1,
	    input_userauth_jpake_client_step1);

	authctxt->postponed = 1;
	return 0;
}

/* ARGSUSED */
static void
input_userauth_jpake_client_step1(int type, u_int32_t seq, void *ctxt)
{
	Authctxt *authctxt = ctxt;
	struct jpake_ctx *pctx = authctxt->jpake_ctx;
	u_char *x1_proof, *x2_proof, *x4_s_proof;
	u_int x1_proof_len, x2_proof_len, x4_s_proof_len;

	/* Disable this message */
	dispatch_set(SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP1, NULL);

	/* Fetch step 1 values */
	if ((pctx->g_x1 = BN_new()) == NULL ||
	    (pctx->g_x2 = BN_new()) == NULL)
		fatal("%s: BN_new", __func__);
	pctx->client_id = packet_get_string(&pctx->client_id_len);
	packet_get_bignum2(pctx->g_x1);
	packet_get_bignum2(pctx->g_x2);
	x1_proof = packet_get_string(&x1_proof_len);
	x2_proof = packet_get_string(&x2_proof_len);
	packet_check_eom();

	if (!use_privsep)
		JPAKE_DEBUG_CTX((pctx, "step 1 received in %s", __func__));

	PRIVSEP(jpake_step2(pctx->grp, pctx->s, pctx->g_x3,
	    pctx->g_x1, pctx->g_x2, pctx->x4,
	    pctx->client_id, pctx->client_id_len,
	    pctx->server_id, pctx->server_id_len,
	    x1_proof, x1_proof_len,
	    x2_proof, x2_proof_len,
	    &pctx->b,
	    &x4_s_proof, &x4_s_proof_len));

	bzero(x1_proof, x1_proof_len);
	bzero(x2_proof, x2_proof_len);
	xfree(x1_proof);
	xfree(x2_proof);

	if (!use_privsep)
		JPAKE_DEBUG_CTX((pctx, "step 2 sending in %s", __func__));

	/* Send values for step 2 */
	packet_start(SSH2_MSG_USERAUTH_JPAKE_SERVER_STEP2);
	packet_put_bignum2(pctx->b);
	packet_put_string(x4_s_proof, x4_s_proof_len);
	packet_send();
	packet_write_wait();

	bzero(x4_s_proof, x4_s_proof_len);
	xfree(x4_s_proof);

	/* Expect step 2 packet from peer */
	dispatch_set(SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP2,
	    input_userauth_jpake_client_step2);
}

/* ARGSUSED */
static void
input_userauth_jpake_client_step2(int type, u_int32_t seq, void *ctxt)
{
	Authctxt *authctxt = ctxt;
	struct jpake_ctx *pctx = authctxt->jpake_ctx;
	u_char *x2_s_proof;
	u_int x2_s_proof_len;

	/* Disable this message */
	dispatch_set(SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP2, NULL);

	if ((pctx->a = BN_new()) == NULL)
		fatal("%s: BN_new", __func__);

	/* Fetch step 2 values */
	packet_get_bignum2(pctx->a);
	x2_s_proof = packet_get_string(&x2_s_proof_len);
	packet_check_eom();

	if (!use_privsep)
		JPAKE_DEBUG_CTX((pctx, "step 2 received in %s", __func__));

	/* Derive shared key and calculate confirmation hash */
	PRIVSEP(jpake_key_confirm(pctx->grp, pctx->s, pctx->a,
	    pctx->x4, pctx->g_x3, pctx->g_x4, pctx->g_x1, pctx->g_x2,
	    pctx->server_id, pctx->server_id_len,
	    pctx->client_id, pctx->client_id_len,
	    session_id2, session_id2_len,
	    x2_s_proof, x2_s_proof_len,
	    &pctx->k,
	    &pctx->h_k_sid_sessid, &pctx->h_k_sid_sessid_len));

	bzero(x2_s_proof, x2_s_proof_len);
	xfree(x2_s_proof);

	if (!use_privsep)
		JPAKE_DEBUG_CTX((pctx, "confirm sending in %s", __func__));

	/* Send key confirmation proof */
	packet_start(SSH2_MSG_USERAUTH_JPAKE_SERVER_CONFIRM);
	packet_put_string(pctx->h_k_sid_sessid, pctx->h_k_sid_sessid_len);
	packet_send();
	packet_write_wait();

	/* Expect confirmation from peer */
	dispatch_set(SSH2_MSG_USERAUTH_JPAKE_CLIENT_CONFIRM,
	    input_userauth_jpake_client_confirm);
}

/* ARGSUSED */
static void
input_userauth_jpake_client_confirm(int type, u_int32_t seq, void *ctxt)
{
	Authctxt *authctxt = ctxt;
	struct jpake_ctx *pctx = authctxt->jpake_ctx;
	int authenticated = 0;

	/* Disable this message */
	dispatch_set(SSH2_MSG_USERAUTH_JPAKE_CLIENT_CONFIRM, NULL);

	pctx->h_k_cid_sessid = packet_get_string(&pctx->h_k_cid_sessid_len);
	packet_check_eom();

	if (!use_privsep)
		JPAKE_DEBUG_CTX((pctx, "confirm received in %s", __func__));

	/* Verify expected confirmation hash */
	if (PRIVSEP(jpake_check_confirm(pctx->k,
	    pctx->client_id, pctx->client_id_len,
	    session_id2, session_id2_len,
	    pctx->h_k_cid_sessid, pctx->h_k_cid_sessid_len)) == 1)
		authenticated = authctxt->valid ? 1 : 0;
	else
		debug("%s: confirmation mismatch", __func__);
		
	/* done */
	authctxt->postponed = 0;
	jpake_free(authctxt->jpake_ctx);
	authctxt->jpake_ctx = NULL;
	userauth_finish(authctxt, authenticated, method_jpake.name);
}

#endif /* JPAKE */

