summaryrefslogtreecommitdiff
path: root/monitor.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2008-11-05 16:20:46 +1100
committerDamien Miller <djm@mindrot.org>2008-11-05 16:20:46 +1100
commit01ed2272a1545336173bf3aef66fbccc3494c8d8 (patch)
treea77f115d3b8964f0b6fcc604f9dea87d15143d7e /monitor.c
parent6f66d34308af787613d5525729953665f26367ee (diff)
- djm@cvs.openbsd.org 2008/11/04 08:22:13
[auth.h auth2.c monitor.c monitor.h monitor_wrap.c monitor_wrap.h] [readconf.c readconf.h servconf.c servconf.h ssh2.h ssh_config.5] [sshconnect2.c sshd_config.5 jpake.c jpake.h schnorr.c auth2-jpake.c] [Makefile.in] Add support for an experimental zero-knowledge password authentication method using the J-PAKE protocol described in F. Hao, P. Ryan, "Password Authenticated Key Exchange by Juggling", 16th Workshop on Security Protocols, Cambridge, April 2008. This method allows password-based authentication without exposing the password to the server. Instead, the client and server exchange cryptographic proofs to demonstrate of knowledge of the password while revealing nothing useful to an attacker or compromised endpoint. This is experimental, work-in-progress code and is presently compiled-time disabled (turn on -DJPAKE in Makefile.inc). "just commit it. It isn't too intrusive." deraadt@
Diffstat (limited to 'monitor.c')
-rw-r--r--monitor.c227
1 files changed, 226 insertions, 1 deletions
diff --git a/monitor.c b/monitor.c
index 73cf6bc9b..39deedc8f 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: monitor.c,v 1.99 2008/07/10 18:08:11 markus Exp $ */ 1/* $OpenBSD: monitor.c,v 1.100 2008/11/04 08:22:13 djm Exp $ */
2/* 2/*
3 * Copyright 2002 Niels Provos <provos@citi.umich.edu> 3 * Copyright 2002 Niels Provos <provos@citi.umich.edu>
4 * Copyright 2002 Markus Friedl <markus@openbsd.org> 4 * Copyright 2002 Markus Friedl <markus@openbsd.org>
@@ -87,6 +87,7 @@
87#include "misc.h" 87#include "misc.h"
88#include "compat.h" 88#include "compat.h"
89#include "ssh2.h" 89#include "ssh2.h"
90#include "jpake.h"
90 91
91#ifdef GSSAPI 92#ifdef GSSAPI
92static Gssctxt *gsscontext = NULL; 93static Gssctxt *gsscontext = NULL;
@@ -149,6 +150,11 @@ int mm_answer_rsa_challenge(int, Buffer *);
149int mm_answer_rsa_response(int, Buffer *); 150int mm_answer_rsa_response(int, Buffer *);
150int mm_answer_sesskey(int, Buffer *); 151int mm_answer_sesskey(int, Buffer *);
151int mm_answer_sessid(int, Buffer *); 152int mm_answer_sessid(int, Buffer *);
153int mm_answer_jpake_get_pwdata(int, Buffer *);
154int mm_answer_jpake_step1(int, Buffer *);
155int mm_answer_jpake_step2(int, Buffer *);
156int mm_answer_jpake_key_confirm(int, Buffer *);
157int mm_answer_jpake_check_confirm(int, Buffer *);
152 158
153#ifdef USE_PAM 159#ifdef USE_PAM
154int mm_answer_pam_start(int, Buffer *); 160int mm_answer_pam_start(int, Buffer *);
@@ -234,6 +240,13 @@ struct mon_table mon_dispatch_proto20[] = {
234 {MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok}, 240 {MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok},
235 {MONITOR_REQ_GSSCHECKMIC, MON_ISAUTH, mm_answer_gss_checkmic}, 241 {MONITOR_REQ_GSSCHECKMIC, MON_ISAUTH, mm_answer_gss_checkmic},
236#endif 242#endif
243#ifdef JPAKE
244 {MONITOR_REQ_JPAKE_GET_PWDATA, MON_ONCE, mm_answer_jpake_get_pwdata},
245 {MONITOR_REQ_JPAKE_STEP1, MON_ISAUTH, mm_answer_jpake_step1},
246 {MONITOR_REQ_JPAKE_STEP2, MON_ONCE, mm_answer_jpake_step2},
247 {MONITOR_REQ_JPAKE_KEY_CONFIRM, MON_ONCE, mm_answer_jpake_key_confirm},
248 {MONITOR_REQ_JPAKE_CHECK_CONFIRM, MON_AUTH, mm_answer_jpake_check_confirm},
249#endif
237 {0, 0, NULL} 250 {0, 0, NULL}
238}; 251};
239 252
@@ -379,6 +392,15 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
379 if (!authenticated) 392 if (!authenticated)
380 authctxt->failures++; 393 authctxt->failures++;
381 } 394 }
395#ifdef JPAKE
396 /* Cleanup JPAKE context after authentication */
397 if (ent->flags & MON_AUTHDECIDE) {
398 if (authctxt->jpake_ctx != NULL) {
399 jpake_free(authctxt->jpake_ctx);
400 authctxt->jpake_ctx = NULL;
401 }
402 }
403#endif
382 } 404 }
383 405
384 if (!authctxt->valid) 406 if (!authctxt->valid)
@@ -1969,3 +1991,206 @@ mm_answer_gss_userok(int sock, Buffer *m)
1969 return (authenticated); 1991 return (authenticated);
1970} 1992}
1971#endif /* GSSAPI */ 1993#endif /* GSSAPI */
1994
1995#ifdef JPAKE
1996int
1997mm_answer_jpake_step1(int sock, Buffer *m)
1998{
1999 struct jpake_ctx *pctx;
2000 u_char *x3_proof, *x4_proof;
2001 u_int x3_proof_len, x4_proof_len;
2002
2003 if (!options.zero_knowledge_password_authentication)
2004 fatal("zero_knowledge_password_authentication disabled");
2005
2006 if (authctxt->jpake_ctx != NULL)
2007 fatal("%s: authctxt->jpake_ctx already set (%p)",
2008 __func__, authctxt->jpake_ctx);
2009 authctxt->jpake_ctx = pctx = jpake_new();
2010
2011 jpake_step1(pctx->grp,
2012 &pctx->server_id, &pctx->server_id_len,
2013 &pctx->x3, &pctx->x4, &pctx->g_x3, &pctx->g_x4,
2014 &x3_proof, &x3_proof_len,
2015 &x4_proof, &x4_proof_len);
2016
2017 JPAKE_DEBUG_CTX((pctx, "step1 done in %s", __func__));
2018
2019 buffer_clear(m);
2020
2021 buffer_put_string(m, pctx->server_id, pctx->server_id_len);
2022 buffer_put_bignum2(m, pctx->g_x3);
2023 buffer_put_bignum2(m, pctx->g_x4);
2024 buffer_put_string(m, x3_proof, x3_proof_len);
2025 buffer_put_string(m, x4_proof, x4_proof_len);
2026
2027 debug3("%s: sending step1", __func__);
2028 mm_request_send(sock, MONITOR_ANS_JPAKE_STEP1, m);
2029
2030 bzero(x3_proof, x3_proof_len);
2031 bzero(x4_proof, x4_proof_len);
2032 xfree(x3_proof);
2033 xfree(x4_proof);
2034
2035 monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_GET_PWDATA, 1);
2036 monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_STEP1, 0);
2037
2038 return 0;
2039}
2040
2041int
2042mm_answer_jpake_get_pwdata(int sock, Buffer *m)
2043{
2044 struct jpake_ctx *pctx = authctxt->jpake_ctx;
2045 char *hash_scheme, *salt;
2046
2047 if (pctx == NULL)
2048 fatal("%s: pctx == NULL", __func__);
2049
2050 auth2_jpake_get_pwdata(authctxt, &pctx->s, &hash_scheme, &salt);
2051
2052 buffer_clear(m);
2053 /* pctx->s is sensitive, not returned to slave */
2054 buffer_put_cstring(m, hash_scheme);
2055 buffer_put_cstring(m, salt);
2056
2057 debug3("%s: sending pwdata", __func__);
2058 mm_request_send(sock, MONITOR_ANS_JPAKE_GET_PWDATA, m);
2059
2060 bzero(hash_scheme, strlen(hash_scheme));
2061 bzero(salt, strlen(salt));
2062 xfree(hash_scheme);
2063 xfree(salt);
2064
2065 monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_STEP2, 1);
2066
2067 return 0;
2068}
2069
2070int
2071mm_answer_jpake_step2(int sock, Buffer *m)
2072{
2073 struct jpake_ctx *pctx = authctxt->jpake_ctx;
2074 u_char *x1_proof, *x2_proof, *x4_s_proof;
2075 u_int x1_proof_len, x2_proof_len, x4_s_proof_len;
2076
2077 if (pctx == NULL)
2078 fatal("%s: pctx == NULL", __func__);
2079
2080 if ((pctx->g_x1 = BN_new()) == NULL ||
2081 (pctx->g_x2 = BN_new()) == NULL)
2082 fatal("%s: BN_new", __func__);
2083 buffer_get_bignum2(m, pctx->g_x1);
2084 buffer_get_bignum2(m, pctx->g_x2);
2085 pctx->client_id = buffer_get_string(m, &pctx->client_id_len);
2086 x1_proof = buffer_get_string(m, &x1_proof_len);
2087 x2_proof = buffer_get_string(m, &x2_proof_len);
2088
2089 jpake_step2(pctx->grp, pctx->s, pctx->g_x3,
2090 pctx->g_x1, pctx->g_x2, pctx->x4,
2091 pctx->client_id, pctx->client_id_len,
2092 pctx->server_id, pctx->server_id_len,
2093 x1_proof, x1_proof_len,
2094 x2_proof, x2_proof_len,
2095 &pctx->b,
2096 &x4_s_proof, &x4_s_proof_len);
2097
2098 JPAKE_DEBUG_CTX((pctx, "step2 done in %s", __func__));
2099
2100 bzero(x1_proof, x1_proof_len);
2101 bzero(x2_proof, x2_proof_len);
2102 xfree(x1_proof);
2103 xfree(x2_proof);
2104
2105 buffer_clear(m);
2106
2107 buffer_put_bignum2(m, pctx->b);
2108 buffer_put_string(m, x4_s_proof, x4_s_proof_len);
2109
2110 debug3("%s: sending step2", __func__);
2111 mm_request_send(sock, MONITOR_ANS_JPAKE_STEP2, m);
2112
2113 bzero(x4_s_proof, x4_s_proof_len);
2114 xfree(x4_s_proof);
2115
2116 monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_KEY_CONFIRM, 1);
2117
2118 return 0;
2119}
2120
2121int
2122mm_answer_jpake_key_confirm(int sock, Buffer *m)
2123{
2124 struct jpake_ctx *pctx = authctxt->jpake_ctx;
2125 u_char *x2_s_proof;
2126 u_int x2_s_proof_len;
2127
2128 if (pctx == NULL)
2129 fatal("%s: pctx == NULL", __func__);
2130
2131 if ((pctx->a = BN_new()) == NULL)
2132 fatal("%s: BN_new", __func__);
2133 buffer_get_bignum2(m, pctx->a);
2134 x2_s_proof = buffer_get_string(m, &x2_s_proof_len);
2135
2136 jpake_key_confirm(pctx->grp, pctx->s, pctx->a,
2137 pctx->x4, pctx->g_x3, pctx->g_x4, pctx->g_x1, pctx->g_x2,
2138 pctx->server_id, pctx->server_id_len,
2139 pctx->client_id, pctx->client_id_len,
2140 session_id2, session_id2_len,
2141 x2_s_proof, x2_s_proof_len,
2142 &pctx->k,
2143 &pctx->h_k_sid_sessid, &pctx->h_k_sid_sessid_len);
2144
2145 JPAKE_DEBUG_CTX((pctx, "key_confirm done in %s", __func__));
2146
2147 bzero(x2_s_proof, x2_s_proof_len);
2148 buffer_clear(m);
2149
2150 /* pctx->k is sensitive, not sent */
2151 buffer_put_string(m, pctx->h_k_sid_sessid, pctx->h_k_sid_sessid_len);
2152
2153 debug3("%s: sending confirmation hash", __func__);
2154 mm_request_send(sock, MONITOR_ANS_JPAKE_KEY_CONFIRM, m);
2155
2156 monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_CHECK_CONFIRM, 1);
2157
2158 return 0;
2159}
2160
2161int
2162mm_answer_jpake_check_confirm(int sock, Buffer *m)
2163{
2164 int authenticated = 0;
2165 u_char *peer_confirm_hash;
2166 u_int peer_confirm_hash_len;
2167 struct jpake_ctx *pctx = authctxt->jpake_ctx;
2168
2169 if (pctx == NULL)
2170 fatal("%s: pctx == NULL", __func__);
2171
2172 peer_confirm_hash = buffer_get_string(m, &peer_confirm_hash_len);
2173
2174 authenticated = jpake_check_confirm(pctx->k,
2175 pctx->client_id, pctx->client_id_len,
2176 session_id2, session_id2_len,
2177 peer_confirm_hash, peer_confirm_hash_len) && authctxt->valid;
2178
2179 JPAKE_DEBUG_CTX((pctx, "check_confirm done in %s", __func__));
2180
2181 bzero(peer_confirm_hash, peer_confirm_hash_len);
2182 xfree(peer_confirm_hash);
2183
2184 buffer_clear(m);
2185 buffer_put_int(m, authenticated);
2186
2187 debug3("%s: sending result %d", __func__, authenticated);
2188 mm_request_send(sock, MONITOR_ANS_JPAKE_CHECK_CONFIRM, m);
2189
2190 monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_STEP1, 1);
2191
2192 auth_method = "jpake-01@openssh.com";
2193 return authenticated;
2194}
2195
2196#endif /* JPAKE */