summaryrefslogtreecommitdiff
path: root/monitor_wrap.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_wrap.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_wrap.c')
-rw-r--r--monitor_wrap.c167
1 files changed, 165 insertions, 2 deletions
diff --git a/monitor_wrap.c b/monitor_wrap.c
index 40463d078..0986fc518 100644
--- a/monitor_wrap.c
+++ b/monitor_wrap.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: monitor_wrap.c,v 1.63 2008/07/10 18:08:11 markus Exp $ */ 1/* $OpenBSD: monitor_wrap.c,v 1.64 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>
@@ -40,6 +40,7 @@
40 40
41#include <openssl/bn.h> 41#include <openssl/bn.h>
42#include <openssl/dh.h> 42#include <openssl/dh.h>
43#include <openssl/evp.h>
43 44
44#include "openbsd-compat/sys-queue.h" 45#include "openbsd-compat/sys-queue.h"
45#include "xmalloc.h" 46#include "xmalloc.h"
@@ -70,7 +71,7 @@
70#include "atomicio.h" 71#include "atomicio.h"
71#include "monitor_fdpass.h" 72#include "monitor_fdpass.h"
72#include "misc.h" 73#include "misc.h"
73#include "servconf.h" 74#include "jpake.h"
74 75
75#include "channels.h" 76#include "channels.h"
76#include "session.h" 77#include "session.h"
@@ -1256,3 +1257,165 @@ mm_ssh_gssapi_userok(char *user)
1256 return (authenticated); 1257 return (authenticated);
1257} 1258}
1258#endif /* GSSAPI */ 1259#endif /* GSSAPI */
1260
1261#ifdef JPAKE
1262void
1263mm_auth2_jpake_get_pwdata(Authctxt *authctxt, BIGNUM **s,
1264 char **hash_scheme, char **salt)
1265{
1266 Buffer m;
1267
1268 debug3("%s entering", __func__);
1269
1270 buffer_init(&m);
1271 mm_request_send(pmonitor->m_recvfd,
1272 MONITOR_REQ_JPAKE_GET_PWDATA, &m);
1273
1274 debug3("%s: waiting for MONITOR_ANS_JPAKE_GET_PWDATA", __func__);
1275 mm_request_receive_expect(pmonitor->m_recvfd,
1276 MONITOR_ANS_JPAKE_GET_PWDATA, &m);
1277
1278 *hash_scheme = buffer_get_string(&m, NULL);
1279 *salt = buffer_get_string(&m, NULL);
1280
1281 buffer_free(&m);
1282}
1283
1284void
1285mm_jpake_step1(struct jpake_group *grp,
1286 u_char **id, u_int *id_len,
1287 BIGNUM **priv1, BIGNUM **priv2, BIGNUM **g_priv1, BIGNUM **g_priv2,
1288 u_char **priv1_proof, u_int *priv1_proof_len,
1289 u_char **priv2_proof, u_int *priv2_proof_len)
1290{
1291 Buffer m;
1292
1293 debug3("%s entering", __func__);
1294
1295 buffer_init(&m);
1296 mm_request_send(pmonitor->m_recvfd,
1297 MONITOR_REQ_JPAKE_STEP1, &m);
1298
1299 debug3("%s: waiting for MONITOR_ANS_JPAKE_STEP1", __func__);
1300 mm_request_receive_expect(pmonitor->m_recvfd,
1301 MONITOR_ANS_JPAKE_STEP1, &m);
1302
1303 if ((*priv1 = BN_new()) == NULL ||
1304 (*priv2 = BN_new()) == NULL ||
1305 (*g_priv1 = BN_new()) == NULL ||
1306 (*g_priv2 = BN_new()) == NULL)
1307 fatal("%s: BN_new", __func__);
1308
1309 *id = buffer_get_string(&m, id_len);
1310 /* priv1 and priv2 are, well, private */
1311 buffer_get_bignum2(&m, *g_priv1);
1312 buffer_get_bignum2(&m, *g_priv2);
1313 *priv1_proof = buffer_get_string(&m, priv1_proof_len);
1314 *priv2_proof = buffer_get_string(&m, priv2_proof_len);
1315
1316 buffer_free(&m);
1317}
1318
1319void
1320mm_jpake_step2(struct jpake_group *grp, BIGNUM *s,
1321 BIGNUM *mypub1, BIGNUM *theirpub1, BIGNUM *theirpub2, BIGNUM *mypriv2,
1322 const u_char *theirid, u_int theirid_len,
1323 const u_char *myid, u_int myid_len,
1324 const u_char *theirpub1_proof, u_int theirpub1_proof_len,
1325 const u_char *theirpub2_proof, u_int theirpub2_proof_len,
1326 BIGNUM **newpub,
1327 u_char **newpub_exponent_proof, u_int *newpub_exponent_proof_len)
1328{
1329 Buffer m;
1330
1331 debug3("%s entering", __func__);
1332
1333 buffer_init(&m);
1334 /* monitor already has all bignums except theirpub1, theirpub2 */
1335 buffer_put_bignum2(&m, theirpub1);
1336 buffer_put_bignum2(&m, theirpub2);
1337 /* monitor already knows our id */
1338 buffer_put_string(&m, theirid, theirid_len);
1339 buffer_put_string(&m, theirpub1_proof, theirpub1_proof_len);
1340 buffer_put_string(&m, theirpub2_proof, theirpub2_proof_len);
1341
1342 mm_request_send(pmonitor->m_recvfd,
1343 MONITOR_REQ_JPAKE_STEP2, &m);
1344
1345 debug3("%s: waiting for MONITOR_ANS_JPAKE_STEP2", __func__);
1346 mm_request_receive_expect(pmonitor->m_recvfd,
1347 MONITOR_ANS_JPAKE_STEP2, &m);
1348
1349 if ((*newpub = BN_new()) == NULL)
1350 fatal("%s: BN_new", __func__);
1351
1352 buffer_get_bignum2(&m, *newpub);
1353 *newpub_exponent_proof = buffer_get_string(&m,
1354 newpub_exponent_proof_len);
1355
1356 buffer_free(&m);
1357}
1358
1359void
1360mm_jpake_key_confirm(struct jpake_group *grp, BIGNUM *s, BIGNUM *step2_val,
1361 BIGNUM *mypriv2, BIGNUM *mypub1, BIGNUM *mypub2,
1362 BIGNUM *theirpub1, BIGNUM *theirpub2,
1363 const u_char *my_id, u_int my_id_len,
1364 const u_char *their_id, u_int their_id_len,
1365 const u_char *sess_id, u_int sess_id_len,
1366 const u_char *theirpriv2_s_proof, u_int theirpriv2_s_proof_len,
1367 BIGNUM **k,
1368 u_char **confirm_hash, u_int *confirm_hash_len)
1369{
1370 Buffer m;
1371
1372 debug3("%s entering", __func__);
1373
1374 buffer_init(&m);
1375 /* monitor already has all bignums except step2_val */
1376 buffer_put_bignum2(&m, step2_val);
1377 /* monitor already knows all the ids */
1378 buffer_put_string(&m, theirpriv2_s_proof, theirpriv2_s_proof_len);
1379
1380 mm_request_send(pmonitor->m_recvfd,
1381 MONITOR_REQ_JPAKE_KEY_CONFIRM, &m);
1382
1383 debug3("%s: waiting for MONITOR_ANS_JPAKE_KEY_CONFIRM", __func__);
1384 mm_request_receive_expect(pmonitor->m_recvfd,
1385 MONITOR_ANS_JPAKE_KEY_CONFIRM, &m);
1386
1387 /* 'k' is sensitive and stays in the monitor */
1388 *confirm_hash = buffer_get_string(&m, confirm_hash_len);
1389
1390 buffer_free(&m);
1391}
1392
1393int
1394mm_jpake_check_confirm(const BIGNUM *k,
1395 const u_char *peer_id, u_int peer_id_len,
1396 const u_char *sess_id, u_int sess_id_len,
1397 const u_char *peer_confirm_hash, u_int peer_confirm_hash_len)
1398{
1399 Buffer m;
1400 int success = 0;
1401
1402 debug3("%s entering", __func__);
1403
1404 buffer_init(&m);
1405 /* k is dummy in slave, ignored */
1406 /* monitor knows all the ids */
1407 buffer_put_string(&m, peer_confirm_hash, peer_confirm_hash_len);
1408 mm_request_send(pmonitor->m_recvfd,
1409 MONITOR_REQ_JPAKE_CHECK_CONFIRM, &m);
1410
1411 debug3("%s: waiting for MONITOR_ANS_JPAKE_CHECK_CONFIRM", __func__);
1412 mm_request_receive_expect(pmonitor->m_recvfd,
1413 MONITOR_ANS_JPAKE_CHECK_CONFIRM, &m);
1414
1415 success = buffer_get_int(&m);
1416 buffer_free(&m);
1417
1418 debug3("%s: success = %d", __func__, success);
1419 return success;
1420}
1421#endif /* JPAKE */