Vendor import of OpenSSH 6.6p1.
This commit is contained in:
parent
45d0197dd7
commit
ab9e0bc082
222
ChangeLog
222
ChangeLog
@ -1,3 +1,224 @@
|
||||
20140313
|
||||
- (djm) Release OpenSSH 6.6
|
||||
|
||||
20140304
|
||||
- OpenBSD CVS Sync
|
||||
- djm@cvs.openbsd.org 2014/03/03 22:22:30
|
||||
[session.c]
|
||||
ignore enviornment variables with embedded '=' or '\0' characters;
|
||||
spotted by Jann Horn; ok deraadt@
|
||||
|
||||
20140301
|
||||
- (djm) [regress/Makefile] Disable dhgex regress test; it breaks when
|
||||
no moduli file exists at the expected location.
|
||||
|
||||
20140228
|
||||
- OpenBSD CVS Sync
|
||||
- djm@cvs.openbsd.org 2014/02/27 00:41:49
|
||||
[bufbn.c]
|
||||
fix unsigned overflow that could lead to reading a short ssh protocol
|
||||
1 bignum value; found by Ben Hawkes; ok deraadt@
|
||||
- djm@cvs.openbsd.org 2014/02/27 08:25:09
|
||||
[bufbn.c]
|
||||
off by one in range check
|
||||
- djm@cvs.openbsd.org 2014/02/27 22:47:07
|
||||
[sshd_config.5]
|
||||
bz#2184 clarify behaviour of a keyword that appears in multiple
|
||||
matching Match blocks; ok dtucker@
|
||||
- djm@cvs.openbsd.org 2014/02/27 22:57:40
|
||||
[version.h]
|
||||
openssh-6.6
|
||||
- dtucker@cvs.openbsd.org 2014/01/19 23:43:02
|
||||
[regress/sftp-chroot.sh]
|
||||
Don't use -q on sftp as it suppresses logging, instead redirect the
|
||||
output to the regress logfile.
|
||||
- dtucker@cvs.openbsd.org 2014/01/20 00:00:30
|
||||
[sregress/ftp-chroot.sh]
|
||||
append to rather than truncating the log file
|
||||
- dtucker@cvs.openbsd.org 2014/01/25 04:35:32
|
||||
[regress/Makefile regress/dhgex.sh]
|
||||
Add a test for DH GEX sizes
|
||||
- djm@cvs.openbsd.org 2014/01/26 10:22:10
|
||||
[regress/cert-hostkey.sh]
|
||||
automatically generate revoked keys from listed keys rather than
|
||||
manually specifying each type; from portable
|
||||
(Id sync only)
|
||||
- djm@cvs.openbsd.org 2014/01/26 10:49:17
|
||||
[scp-ssh-wrapper.sh scp.sh]
|
||||
make sure $SCP is tested on the remote end rather than whichever one
|
||||
happens to be in $PATH; from portable
|
||||
(Id sync only)
|
||||
- djm@cvs.openbsd.org 2014/02/27 20:04:16
|
||||
[login-timeout.sh]
|
||||
remove any existing LoginGraceTime from sshd_config before adding
|
||||
a specific one for the test back in
|
||||
- djm@cvs.openbsd.org 2014/02/27 21:21:25
|
||||
[agent-ptrace.sh agent.sh]
|
||||
keep return values that are printed in error messages;
|
||||
from portable
|
||||
(Id sync only)
|
||||
- (djm) [README contrib/caldera/openssh.spec contrib/redhat/openssh.spec]
|
||||
[contrib/suse/openssh.spec] Crank version numbers
|
||||
- (djm) [regress/host-expand.sh] Add RCS Id
|
||||
|
||||
20140227
|
||||
- OpenBSD CVS Sync
|
||||
- djm@cvs.openbsd.org 2014/02/26 20:18:37
|
||||
[ssh.c]
|
||||
bz#2205: avoid early hostname lookups unless canonicalisation is enabled;
|
||||
ok dtucker@ markus@
|
||||
- djm@cvs.openbsd.org 2014/02/26 20:28:44
|
||||
[auth2-gss.c gss-serv.c ssh-gss.h sshd.c]
|
||||
bz#2107 - cache OIDs of supported GSSAPI mechanisms before privsep
|
||||
sandboxing, as running this code in the sandbox can cause violations;
|
||||
ok markus@
|
||||
- djm@cvs.openbsd.org 2014/02/26 20:29:29
|
||||
[channels.c]
|
||||
don't assume that the socks4 username is \0 terminated;
|
||||
spotted by Ben Hawkes; ok markus@
|
||||
- markus@cvs.openbsd.org 2014/02/26 21:53:37
|
||||
[sshd.c]
|
||||
ssh_gssapi_prepare_supported_oids needs GSSAPI
|
||||
|
||||
20140224
|
||||
- OpenBSD CVS Sync
|
||||
- djm@cvs.openbsd.org 2014/02/07 06:55:54
|
||||
[cipher.c mac.c]
|
||||
remove some logging that makes ssh debugging output very verbose;
|
||||
ok markus
|
||||
- djm@cvs.openbsd.org 2014/02/15 23:05:36
|
||||
[channels.c]
|
||||
avoid spurious "getsockname failed: Bad file descriptor" errors in ssh -W;
|
||||
bz#2200, debian#738692 via Colin Watson; ok dtucker@
|
||||
- djm@cvs.openbsd.org 2014/02/22 01:32:19
|
||||
[readconf.c]
|
||||
when processing Match blocks, skip 'exec' clauses if previous predicates
|
||||
failed to match; ok markus@
|
||||
- djm@cvs.openbsd.org 2014/02/23 20:03:42
|
||||
[ssh-ed25519.c]
|
||||
check for unsigned overflow; not reachable in OpenSSH but others might
|
||||
copy our code...
|
||||
- djm@cvs.openbsd.org 2014/02/23 20:11:36
|
||||
[readconf.c readconf.h ssh.c ssh_config.5]
|
||||
reparse ssh_config and ~/.ssh/config if hostname canonicalisation changes
|
||||
the hostname. This allows users to write configurations that always
|
||||
refer to canonical hostnames, e.g.
|
||||
|
||||
CanonicalizeHostname yes
|
||||
CanonicalDomains int.example.org example.org
|
||||
CanonicalizeFallbackLocal no
|
||||
|
||||
Host *.int.example.org
|
||||
Compression off
|
||||
Host *.example.org
|
||||
User djm
|
||||
|
||||
ok markus@
|
||||
|
||||
20140213
|
||||
- (dtucker) [configure.ac openbsd-compat/openssl-compat.{c,h}] Add compat
|
||||
code for older OpenSSL versions that don't have EVP_MD_CTX_copy_ex.
|
||||
|
||||
20140207
|
||||
- OpenBSD CVS Sync
|
||||
- naddy@cvs.openbsd.org 2014/02/05 20:13:25
|
||||
[ssh-keygen.1 ssh-keygen.c]
|
||||
tweak synopsis: calling ssh-keygen without any arguments is fine; ok jmc@
|
||||
while here, fix ordering in usage(); requested by jmc@
|
||||
- djm@cvs.openbsd.org 2014/02/06 22:21:01
|
||||
[sshconnect.c]
|
||||
in ssh_create_socket(), only do the getaddrinfo for BindAddress when
|
||||
BindAddress is actually specified. Fixes regression in 6.5 for
|
||||
UsePrivilegedPort=yes; patch from Corinna Vinschen
|
||||
|
||||
20140206
|
||||
- (dtucker) [openbsd-compat/bsd-poll.c] Don't bother checking for non-NULL
|
||||
before freeing since free(NULL) is a no-op. ok djm.
|
||||
- (djm) [sandbox-seccomp-filter.c] Not all Linux architectures define
|
||||
__NR_shutdown; some go via the socketcall(2) multiplexer.
|
||||
|
||||
20140205
|
||||
- (djm) [sandbox-capsicum.c] Don't fatal if Capsicum is offered by
|
||||
headers/libc but not supported by the kernel. Patch from Loganaden
|
||||
Velvindron @ AfriNIC
|
||||
|
||||
20140204
|
||||
- OpenBSD CVS Sync
|
||||
- markus@cvs.openbsd.org 2014/01/27 18:58:14
|
||||
[Makefile.in digest.c digest.h hostfile.c kex.h mac.c hmac.c hmac.h]
|
||||
replace openssl HMAC with an implementation based on our ssh_digest_*
|
||||
ok and feedback djm@
|
||||
- markus@cvs.openbsd.org 2014/01/27 19:18:54
|
||||
[auth-rsa.c cipher.c ssh-agent.c sshconnect1.c sshd.c]
|
||||
replace openssl MD5 with our ssh_digest_*; ok djm@
|
||||
- markus@cvs.openbsd.org 2014/01/27 20:13:46
|
||||
[digest.c digest-openssl.c digest-libc.c Makefile.in]
|
||||
rename digest.c to digest-openssl.c and add libc variant; ok djm@
|
||||
- jmc@cvs.openbsd.org 2014/01/28 14:13:39
|
||||
[ssh-keyscan.1]
|
||||
kill some bad Pa;
|
||||
From: Jan Stary
|
||||
- djm@cvs.openbsd.org 2014/01/29 00:19:26
|
||||
[sshd.c]
|
||||
use kill(0, ...) instead of killpg(0, ...); on most operating systems
|
||||
they are equivalent, but SUSv2 describes the latter as having undefined
|
||||
behaviour; from portable; ok dtucker
|
||||
(Id sync only; change is already in portable)
|
||||
- djm@cvs.openbsd.org 2014/01/29 06:18:35
|
||||
[Makefile.in auth.h auth2-jpake.c auth2.c jpake.c jpake.h monitor.c]
|
||||
[monitor.h monitor_wrap.c monitor_wrap.h readconf.c readconf.h]
|
||||
[schnorr.c schnorr.h servconf.c servconf.h ssh2.h sshconnect2.c]
|
||||
remove experimental, never-enabled JPAKE code; ok markus@
|
||||
- jmc@cvs.openbsd.org 2014/01/29 14:04:51
|
||||
[sshd_config.5]
|
||||
document kbdinteractiveauthentication;
|
||||
requested From: Ross L Richardson
|
||||
|
||||
dtucker/markus helped explain its workings;
|
||||
- djm@cvs.openbsd.org 2014/01/30 22:26:14
|
||||
[sandbox-systrace.c]
|
||||
allow shutdown(2) syscall in sandbox - it may be called by packet_close()
|
||||
from portable
|
||||
(Id sync only; change is already in portable)
|
||||
- tedu@cvs.openbsd.org 2014/01/31 16:39:19
|
||||
[auth2-chall.c authfd.c authfile.c bufaux.c bufec.c canohost.c]
|
||||
[channels.c cipher-chachapoly.c clientloop.c configure.ac hostfile.c]
|
||||
[kexc25519.c krl.c monitor.c sandbox-systrace.c session.c]
|
||||
[sftp-client.c ssh-keygen.c ssh.c sshconnect2.c sshd.c sshlogin.c]
|
||||
[openbsd-compat/explicit_bzero.c openbsd-compat/openbsd-compat.h]
|
||||
replace most bzero with explicit_bzero, except a few that cna be memset
|
||||
ok djm dtucker
|
||||
- djm@cvs.openbsd.org 2014/02/02 03:44:32
|
||||
[auth1.c auth2-chall.c auth2-passwd.c authfile.c bufaux.c bufbn.c]
|
||||
[buffer.c cipher-3des1.c cipher.c clientloop.c gss-serv.c kex.c]
|
||||
[kexdhc.c kexdhs.c kexecdhc.c kexgexc.c kexecdhs.c kexgexs.c key.c]
|
||||
[monitor.c monitor_wrap.c packet.c readpass.c rsa.c serverloop.c]
|
||||
[ssh-add.c ssh-agent.c ssh-dss.c ssh-ecdsa.c ssh-ed25519.c]
|
||||
[ssh-keygen.c ssh-rsa.c sshconnect.c sshconnect1.c sshconnect2.c]
|
||||
[sshd.c]
|
||||
convert memset of potentially-private data to explicit_bzero()
|
||||
- djm@cvs.openbsd.org 2014/02/03 23:28:00
|
||||
[ssh-ecdsa.c]
|
||||
fix memory leak; ECDSA_SIG_new() allocates 'r' and 's' for us, unlike
|
||||
DSA_SIG_new. Reported by Batz Spear; ok markus@
|
||||
- djm@cvs.openbsd.org 2014/02/02 03:44:31
|
||||
[digest-libc.c digest-openssl.c]
|
||||
convert memset of potentially-private data to explicit_bzero()
|
||||
- djm@cvs.openbsd.org 2014/02/04 00:24:29
|
||||
[ssh.c]
|
||||
delay lowercasing of hostname until right before hostname
|
||||
canonicalisation to unbreak case-sensitive matching of ssh_config;
|
||||
reported by Ike Devolder; ok markus@
|
||||
- (djm) [openbsd-compat/Makefile.in] Add missing explicit_bzero.o
|
||||
- (djm) [regress/setuid-allowed.c] Missing string.h for strerror()
|
||||
|
||||
20140131
|
||||
- (djm) [sandbox-seccomp-filter.c sandbox-systrace.c] Allow shutdown(2)
|
||||
syscall from sandboxes; it may be called by packet_close.
|
||||
- (dtucker) [readconf.c] Include <arpa/inet.h> for the hton macros. Fixes
|
||||
build with HP-UX's compiler. Patch from Kevin Brott.
|
||||
- (tim) [Makefile.in] build regress/setuid-allow.
|
||||
|
||||
20140130
|
||||
- (djm) [configure.ac] Only check for width-specified integer types
|
||||
in headers that actually exist. patch from Tom G. Christensen;
|
||||
@ -2663,3 +2884,4 @@
|
||||
[contrib/suse/openssh.spec] Update for release 6.0
|
||||
- (djm) [README] Update URL to release notes.
|
||||
- (djm) Release openssh-6.0
|
||||
|
||||
|
10
Makefile.in
10
Makefile.in
@ -1,4 +1,4 @@
|
||||
# $Id: Makefile.in,v 1.352 2014/01/27 06:35:04 dtucker Exp $
|
||||
# $Id: Makefile.in,v 1.356 2014/02/04 00:12:56 djm Exp $
|
||||
|
||||
# uncomment if you run a non bourne compatable shell. Ie. csh
|
||||
#SHELL = @SH@
|
||||
@ -73,9 +73,9 @@ LIBSSH_OBJS=authfd.o authfile.o bufaux.o bufbn.o buffer.o \
|
||||
monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-rsa.o dh.o \
|
||||
kexdh.o kexgex.o kexdhc.o kexgexc.o bufec.o kexecdh.o kexecdhc.o \
|
||||
msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \
|
||||
jpake.o schnorr.o ssh-pkcs11.o krl.o smult_curve25519_ref.o \
|
||||
ssh-pkcs11.o krl.o smult_curve25519_ref.o \
|
||||
kexc25519.o kexc25519c.o poly1305.o chacha.o cipher-chachapoly.o \
|
||||
ssh-ed25519.o digest.o \
|
||||
ssh-ed25519.o digest-openssl.o hmac.o \
|
||||
sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o blocks.o
|
||||
|
||||
SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \
|
||||
@ -88,7 +88,7 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \
|
||||
auth.o auth1.o auth2.o auth-options.o session.o \
|
||||
auth-chall.o auth2-chall.o groupaccess.o \
|
||||
auth-skey.o auth-bsdauth.o auth2-hostbased.o auth2-kbdint.o \
|
||||
auth2-none.o auth2-passwd.o auth2-pubkey.o auth2-jpake.o \
|
||||
auth2-none.o auth2-passwd.o auth2-pubkey.o \
|
||||
monitor_mm.o monitor.o monitor_wrap.o kexdhs.o kexgexs.o kexecdhs.o \
|
||||
kexc25519s.o auth-krb5.o \
|
||||
auth2-gss.o gss-serv.o gss-serv-krb5.o \
|
||||
@ -408,7 +408,7 @@ regress/setuid-allowed$(EXEEXT): $(srcdir)/regress/setuid-allowed.c
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $? \
|
||||
$(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS)
|
||||
|
||||
tests interop-tests: $(TARGETS) regress/modpipe$(EXEEXT)
|
||||
tests interop-tests: $(TARGETS) regress/modpipe$(EXEEXT) regress/setuid-allowed$(EXEEXT)
|
||||
BUILDDIR=`pwd`; \
|
||||
TEST_SHELL="@TEST_SHELL@"; \
|
||||
TEST_SSH_SCP="$${BUILDDIR}/scp"; \
|
||||
|
4
README
4
README
@ -1,4 +1,4 @@
|
||||
See http://www.openssh.com/txt/release-6.5 for the release notes.
|
||||
See http://www.openssh.com/txt/release-6.6 for the release notes.
|
||||
|
||||
- A Japanese translation of this document and of the OpenSSH FAQ is
|
||||
- available at http://www.unixuser.org/~haruyama/security/openssh/index.html
|
||||
@ -62,4 +62,4 @@ References -
|
||||
[6] http://www.openbsd.org/cgi-bin/man.cgi?query=style&sektion=9
|
||||
[7] http://www.openssh.com/faq.html
|
||||
|
||||
$Id: README,v 1.85 2014/01/16 07:51:45 djm Exp $
|
||||
$Id: README,v 1.86 2014/02/27 23:03:53 djm Exp $
|
||||
|
22
auth-rsa.c
22
auth-rsa.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: auth-rsa.c,v 1.85 2013/07/12 00:19:58 djm Exp $ */
|
||||
/* $OpenBSD: auth-rsa.c,v 1.86 2014/01/27 19:18:54 markus Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@ -20,7 +20,6 @@
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/md5.h>
|
||||
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
@ -48,6 +47,8 @@
|
||||
#include "ssh.h"
|
||||
#include "misc.h"
|
||||
|
||||
#include "digest.h"
|
||||
|
||||
/* import */
|
||||
extern ServerOptions options;
|
||||
|
||||
@ -91,12 +92,13 @@ int
|
||||
auth_rsa_verify_response(Key *key, BIGNUM *challenge, u_char response[16])
|
||||
{
|
||||
u_char buf[32], mdbuf[16];
|
||||
MD5_CTX md;
|
||||
struct ssh_digest_ctx *md;
|
||||
int len;
|
||||
|
||||
/* don't allow short keys */
|
||||
if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
|
||||
error("auth_rsa_verify_response: RSA modulus too small: %d < minimum %d bits",
|
||||
error("%s: RSA modulus too small: %d < minimum %d bits",
|
||||
__func__,
|
||||
BN_num_bits(key->rsa->n), SSH_RSA_MINIMUM_MODULUS_SIZE);
|
||||
return (0);
|
||||
}
|
||||
@ -104,13 +106,15 @@ auth_rsa_verify_response(Key *key, BIGNUM *challenge, u_char response[16])
|
||||
/* The response is MD5 of decrypted challenge plus session id. */
|
||||
len = BN_num_bytes(challenge);
|
||||
if (len <= 0 || len > 32)
|
||||
fatal("auth_rsa_verify_response: bad challenge length %d", len);
|
||||
fatal("%s: bad challenge length %d", __func__, len);
|
||||
memset(buf, 0, 32);
|
||||
BN_bn2bin(challenge, buf + 32 - len);
|
||||
MD5_Init(&md);
|
||||
MD5_Update(&md, buf, 32);
|
||||
MD5_Update(&md, session_id, 16);
|
||||
MD5_Final(mdbuf, &md);
|
||||
if ((md = ssh_digest_start(SSH_DIGEST_MD5)) == NULL ||
|
||||
ssh_digest_update(md, buf, 32) < 0 ||
|
||||
ssh_digest_update(md, session_id, 16) < 0 ||
|
||||
ssh_digest_final(md, mdbuf, sizeof(mdbuf)) < 0)
|
||||
fatal("%s: md5 failed", __func__);
|
||||
ssh_digest_free(md);
|
||||
|
||||
/* Verify that the response is the original challenge. */
|
||||
if (timingsafe_bcmp(response, mdbuf, 16) != 0) {
|
||||
|
6
auth.h
6
auth.h
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: auth.h,v 1.76 2013/07/19 07:37:48 markus Exp $ */
|
||||
/* $OpenBSD: auth.h,v 1.77 2014/01/29 06:18:35 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
@ -61,7 +61,6 @@ struct Authctxt {
|
||||
char *style;
|
||||
void *kbdintctxt;
|
||||
char *info; /* Extra info for next auth_log */
|
||||
void *jpake_ctx;
|
||||
#ifdef BSD_AUTH
|
||||
auth_session_t *as;
|
||||
#endif
|
||||
@ -175,9 +174,6 @@ int bsdauth_respond(void *, u_int, char **);
|
||||
int skey_query(void *, char **, char **, u_int *, char ***, u_int **);
|
||||
int skey_respond(void *, u_int, char **);
|
||||
|
||||
void auth2_jpake_get_pwdata(Authctxt *, BIGNUM **, char **, char **);
|
||||
void auth2_jpake_stop(Authctxt *);
|
||||
|
||||
int allowed_user(struct passwd *);
|
||||
struct passwd * getpwnamallow(const char *user);
|
||||
|
||||
|
6
auth1.c
6
auth1.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: auth1.c,v 1.79 2013/05/19 02:42:42 djm Exp $ */
|
||||
/* $OpenBSD: auth1.c,v 1.80 2014/02/02 03:44:31 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
@ -129,7 +129,7 @@ auth1_process_password(Authctxt *authctxt)
|
||||
/* Try authentication with the password. */
|
||||
authenticated = PRIVSEP(auth_password(authctxt, password));
|
||||
|
||||
memset(password, 0, dlen);
|
||||
explicit_bzero(password, dlen);
|
||||
free(password);
|
||||
|
||||
return (authenticated);
|
||||
@ -222,7 +222,7 @@ auth1_process_tis_response(Authctxt *authctxt)
|
||||
response = packet_get_string(&dlen);
|
||||
packet_check_eom();
|
||||
authenticated = verify_response(authctxt, response);
|
||||
memset(response, 'r', dlen);
|
||||
explicit_bzero(response, dlen);
|
||||
free(response);
|
||||
|
||||
return (authenticated);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: auth2-chall.c,v 1.39 2013/11/08 00:39:14 djm Exp $ */
|
||||
/* $OpenBSD: auth2-chall.c,v 1.41 2014/02/02 03:44:31 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2001 Markus Friedl. All rights reserved.
|
||||
* Copyright (c) 2001 Per Allansson. All rights reserved.
|
||||
@ -148,7 +148,7 @@ kbdint_free(KbdintAuthctxt *kbdintctxt)
|
||||
if (kbdintctxt->device)
|
||||
kbdint_reset_device(kbdintctxt);
|
||||
free(kbdintctxt->devices);
|
||||
bzero(kbdintctxt, sizeof(*kbdintctxt));
|
||||
explicit_bzero(kbdintctxt, sizeof(*kbdintctxt));
|
||||
free(kbdintctxt);
|
||||
}
|
||||
/* get next device */
|
||||
@ -312,7 +312,7 @@ input_userauth_info_response(int type, u_int32_t seq, void *ctxt)
|
||||
res = kbdintctxt->device->respond(kbdintctxt->ctxt, nresp, response);
|
||||
|
||||
for (i = 0; i < nresp; i++) {
|
||||
memset(response[i], 'r', strlen(response[i]));
|
||||
explicit_bzero(response[i], strlen(response[i]));
|
||||
free(response[i]);
|
||||
}
|
||||
free(response);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: auth2-gss.c,v 1.20 2013/05/17 00:13:13 djm Exp $ */
|
||||
/* $OpenBSD: auth2-gss.c,v 1.21 2014/02/26 20:28:44 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
|
||||
@ -62,7 +62,6 @@ userauth_gssapi(Authctxt *authctxt)
|
||||
gss_OID_desc goid = {0, NULL};
|
||||
Gssctxt *ctxt = NULL;
|
||||
int mechs;
|
||||
gss_OID_set supported;
|
||||
int present;
|
||||
OM_uint32 ms;
|
||||
u_int len;
|
||||
@ -77,7 +76,6 @@ userauth_gssapi(Authctxt *authctxt)
|
||||
return (0);
|
||||
}
|
||||
|
||||
ssh_gssapi_supported_oids(&supported);
|
||||
do {
|
||||
mechs--;
|
||||
|
||||
@ -90,15 +88,12 @@ userauth_gssapi(Authctxt *authctxt)
|
||||
doid[1] == len - 2) {
|
||||
goid.elements = doid + 2;
|
||||
goid.length = len - 2;
|
||||
gss_test_oid_set_member(&ms, &goid, supported,
|
||||
&present);
|
||||
ssh_gssapi_test_oid_supported(&ms, &goid, &present);
|
||||
} else {
|
||||
logit("Badly formed OID received");
|
||||
}
|
||||
} while (mechs > 0 && !present);
|
||||
|
||||
gss_release_oid_set(&ms, &supported);
|
||||
|
||||
if (!present) {
|
||||
free(doid);
|
||||
authctxt->server_caused_failure = 1;
|
||||
|
563
auth2-jpake.c
563
auth2-jpake.c
@ -1,563 +0,0 @@
|
||||
/* $OpenBSD: auth2-jpake.c,v 1.6 2013/05/17 00:13:13 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);
|
||||
free(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");
|
||||
}
|
||||
free(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);
|
||||
free(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));
|
||||
free(hash_scheme);
|
||||
free(salt);
|
||||
bzero(x3_proof, x3_proof_len);
|
||||
bzero(x4_proof, x4_proof_len);
|
||||
free(x3_proof);
|
||||
free(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);
|
||||
free(x1_proof);
|
||||
free(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);
|
||||
free(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);
|
||||
free(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, NULL);
|
||||
}
|
||||
|
||||
#endif /* JPAKE */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: auth2-passwd.c,v 1.10 2013/05/17 00:13:13 djm Exp $ */
|
||||
/* $OpenBSD: auth2-passwd.c,v 1.11 2014/02/02 03:44:31 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
*
|
||||
@ -59,7 +59,7 @@ userauth_passwd(Authctxt *authctxt)
|
||||
if (change) {
|
||||
/* discard new password from packet */
|
||||
newpass = packet_get_string(&newlen);
|
||||
memset(newpass, 0, newlen);
|
||||
explicit_bzero(newpass, newlen);
|
||||
free(newpass);
|
||||
}
|
||||
packet_check_eom();
|
||||
@ -68,7 +68,7 @@ userauth_passwd(Authctxt *authctxt)
|
||||
logit("password change not supported");
|
||||
else if (PRIVSEP(auth_password(authctxt, password)) == 1)
|
||||
authenticated = 1;
|
||||
memset(password, 0, len);
|
||||
explicit_bzero(password, len);
|
||||
free(password);
|
||||
return authenticated;
|
||||
}
|
||||
|
11
auth2.c
11
auth2.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: auth2.c,v 1.129 2013/05/19 02:42:42 djm Exp $ */
|
||||
/* $OpenBSD: auth2.c,v 1.130 2014/01/29 06:18:35 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
*
|
||||
@ -71,18 +71,12 @@ extern Authmethod method_hostbased;
|
||||
#ifdef GSSAPI
|
||||
extern Authmethod method_gssapi;
|
||||
#endif
|
||||
#ifdef JPAKE
|
||||
extern Authmethod method_jpake;
|
||||
#endif
|
||||
|
||||
Authmethod *authmethods[] = {
|
||||
&method_none,
|
||||
&method_pubkey,
|
||||
#ifdef GSSAPI
|
||||
&method_gssapi,
|
||||
#endif
|
||||
#ifdef JPAKE
|
||||
&method_jpake,
|
||||
#endif
|
||||
&method_passwd,
|
||||
&method_kbdint,
|
||||
@ -270,9 +264,6 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt)
|
||||
}
|
||||
/* reset state */
|
||||
auth2_challenge_stop(authctxt);
|
||||
#ifdef JPAKE
|
||||
auth2_jpake_stop(authctxt);
|
||||
#endif
|
||||
|
||||
#ifdef GSSAPI
|
||||
/* XXX move to auth2_gssapi_stop() */
|
||||
|
4
authfd.c
4
authfd.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: authfd.c,v 1.91 2013/12/29 04:29:25 djm Exp $ */
|
||||
/* $OpenBSD: authfd.c,v 1.92 2014/01/31 16:39:19 tedu Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@ -102,7 +102,7 @@ ssh_get_authentication_socket(void)
|
||||
if (!authsocket)
|
||||
return -1;
|
||||
|
||||
bzero(&sunaddr, sizeof(sunaddr));
|
||||
memset(&sunaddr, 0, sizeof(sunaddr));
|
||||
sunaddr.sun_family = AF_UNIX;
|
||||
strlcpy(sunaddr.sun_path, authsocket, sizeof(sunaddr.sun_path));
|
||||
|
||||
|
20
authfile.c
20
authfile.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: authfile.c,v 1.101 2013/12/29 04:35:50 djm Exp $ */
|
||||
/* $OpenBSD: authfile.c,v 1.103 2014/02/02 03:44:31 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@ -131,7 +131,7 @@ key_private_to_blob2(Key *prv, Buffer *blob, const char *passphrase,
|
||||
buffer_put_int(&kdf, rounds);
|
||||
}
|
||||
cipher_init(&ctx, c, key, keylen, key + keylen , ivlen, 1);
|
||||
memset(key, 0, keylen + ivlen);
|
||||
explicit_bzero(key, keylen + ivlen);
|
||||
free(key);
|
||||
|
||||
buffer_init(&encoded);
|
||||
@ -143,7 +143,7 @@ key_private_to_blob2(Key *prv, Buffer *blob, const char *passphrase,
|
||||
key_to_blob(prv, &cp, &len); /* public key */
|
||||
buffer_put_string(&encoded, cp, len);
|
||||
|
||||
memset(cp, 0, len);
|
||||
explicit_bzero(cp, len);
|
||||
free(cp);
|
||||
|
||||
buffer_free(&kdf);
|
||||
@ -409,7 +409,7 @@ key_parse_private2(Buffer *blob, int type, const char *passphrase,
|
||||
free(salt);
|
||||
free(comment);
|
||||
if (key)
|
||||
memset(key, 0, keylen + ivlen);
|
||||
explicit_bzero(key, keylen + ivlen);
|
||||
free(key);
|
||||
buffer_free(&encoded);
|
||||
buffer_free(©);
|
||||
@ -496,10 +496,10 @@ key_private_rsa1_to_blob(Key *key, Buffer *blob, const char *passphrase,
|
||||
buffer_ptr(&buffer), buffer_len(&buffer), 0, 0) != 0)
|
||||
fatal("%s: cipher_crypt failed", __func__);
|
||||
cipher_cleanup(&ciphercontext);
|
||||
memset(&ciphercontext, 0, sizeof(ciphercontext));
|
||||
explicit_bzero(&ciphercontext, sizeof(ciphercontext));
|
||||
|
||||
/* Destroy temporary data. */
|
||||
memset(buf, 0, sizeof(buf));
|
||||
explicit_bzero(buf, sizeof(buf));
|
||||
buffer_free(&buffer);
|
||||
|
||||
buffer_append(blob, buffer_ptr(&encrypted), buffer_len(&encrypted));
|
||||
@ -703,17 +703,17 @@ key_load_file(int fd, const char *filename, Buffer *blob)
|
||||
__func__, filename == NULL ? "" : filename,
|
||||
filename == NULL ? "" : " ", strerror(errno));
|
||||
buffer_clear(blob);
|
||||
bzero(buf, sizeof(buf));
|
||||
explicit_bzero(buf, sizeof(buf));
|
||||
return 0;
|
||||
}
|
||||
buffer_append(blob, buf, len);
|
||||
if (buffer_len(blob) > MAX_KEY_FILE_SIZE) {
|
||||
buffer_clear(blob);
|
||||
bzero(buf, sizeof(buf));
|
||||
explicit_bzero(buf, sizeof(buf));
|
||||
goto toobig;
|
||||
}
|
||||
}
|
||||
bzero(buf, sizeof(buf));
|
||||
explicit_bzero(buf, sizeof(buf));
|
||||
if ((st.st_mode & (S_IFSOCK|S_IFCHR|S_IFIFO)) == 0 &&
|
||||
st.st_size != buffer_len(blob)) {
|
||||
debug("%s: key file %.200s%schanged size while reading",
|
||||
@ -831,7 +831,7 @@ key_parse_private_rsa1(Buffer *blob, const char *passphrase, char **commentp)
|
||||
buffer_ptr(©), buffer_len(©), 0, 0) != 0)
|
||||
fatal("%s: cipher_crypt failed", __func__);
|
||||
cipher_cleanup(&ciphercontext);
|
||||
memset(&ciphercontext, 0, sizeof(ciphercontext));
|
||||
explicit_bzero(&ciphercontext, sizeof(ciphercontext));
|
||||
buffer_free(©);
|
||||
|
||||
check1 = buffer_get_char(&decrypted);
|
||||
|
8
bufaux.c
8
bufaux.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: bufaux.c,v 1.54 2014/01/12 08:13:13 djm Exp $ */
|
||||
/* $OpenBSD: bufaux.c,v 1.56 2014/02/02 03:44:31 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@ -216,7 +216,7 @@ buffer_get_cstring_ret(Buffer *buffer, u_int *length_ptr)
|
||||
if (cp == ret + length - 1)
|
||||
error("buffer_get_cstring_ret: string contains \\0");
|
||||
else {
|
||||
bzero(ret, length);
|
||||
explicit_bzero(ret, length);
|
||||
free(ret);
|
||||
return NULL;
|
||||
}
|
||||
@ -346,7 +346,7 @@ buffer_get_bignum2_as_string_ret(Buffer *buffer, u_int *length_ptr)
|
||||
}
|
||||
ret = xmalloc(len);
|
||||
memcpy(ret, p, len);
|
||||
memset(p, '\0', len);
|
||||
explicit_bzero(p, len);
|
||||
free(bin);
|
||||
return ret;
|
||||
}
|
||||
@ -383,7 +383,7 @@ buffer_put_bignum2_from_string(Buffer *buffer, const u_char *s, u_int l)
|
||||
}
|
||||
memcpy(p, s, l);
|
||||
buffer_put_string(buffer, buf, l + pad);
|
||||
memset(buf, '\0', l + pad);
|
||||
explicit_bzero(buf, l + pad);
|
||||
free(buf);
|
||||
}
|
||||
|
||||
|
11
bufbn.c
11
bufbn.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: bufbn.c,v 1.8 2013/11/08 11:15:19 dtucker Exp $*/
|
||||
/* $OpenBSD: bufbn.c,v 1.11 2014/02/27 08:25:09 djm Exp $*/
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@ -80,7 +80,7 @@ buffer_put_bignum_ret(Buffer *buffer, const BIGNUM *value)
|
||||
/* Store the binary data. */
|
||||
buffer_append(buffer, buf, oi);
|
||||
|
||||
memset(buf, 0, bin_size);
|
||||
explicit_bzero(buf, bin_size);
|
||||
free(buf);
|
||||
|
||||
return (0);
|
||||
@ -108,6 +108,11 @@ buffer_get_bignum_ret(Buffer *buffer, BIGNUM *value)
|
||||
return (-1);
|
||||
}
|
||||
bits = get_u16(buf);
|
||||
if (bits > 65535-7) {
|
||||
error("buffer_get_bignum_ret: cannot handle BN of size %d",
|
||||
bits);
|
||||
return (-1);
|
||||
}
|
||||
/* Compute the number of binary bytes that follow. */
|
||||
bytes = (bits + 7) / 8;
|
||||
if (bytes > 8 * 1024) {
|
||||
@ -173,7 +178,7 @@ buffer_put_bignum2_ret(Buffer *buffer, const BIGNUM *value)
|
||||
}
|
||||
hasnohigh = (buf[1] & 0x80) ? 0 : 1;
|
||||
buffer_put_string(buffer, buf+hasnohigh, bytes-hasnohigh);
|
||||
memset(buf, 0, bytes);
|
||||
explicit_bzero(buf, bytes);
|
||||
free(buf);
|
||||
return (0);
|
||||
}
|
||||
|
6
bufec.c
6
bufec.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: bufec.c,v 1.2 2013/05/17 00:13:13 djm Exp $ */
|
||||
/* $OpenBSD: bufec.c,v 1.3 2014/01/31 16:39:19 tedu Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2010 Damien Miller <djm@mindrot.org>
|
||||
*
|
||||
@ -77,7 +77,7 @@ buffer_put_ecpoint_ret(Buffer *buffer, const EC_GROUP *curve,
|
||||
ret = 0;
|
||||
out:
|
||||
if (buf != NULL) {
|
||||
bzero(buf, len);
|
||||
explicit_bzero(buf, len);
|
||||
free(buf);
|
||||
}
|
||||
BN_CTX_free(bnctx);
|
||||
@ -130,7 +130,7 @@ buffer_get_ecpoint_ret(Buffer *buffer, const EC_GROUP *curve,
|
||||
ret = 0;
|
||||
out:
|
||||
BN_CTX_free(bnctx);
|
||||
bzero(buf, len);
|
||||
explicit_bzero(buf, len);
|
||||
free(buf);
|
||||
return ret;
|
||||
}
|
||||
|
4
buffer.c
4
buffer.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: buffer.c,v 1.34 2013/11/08 11:15:19 dtucker Exp $ */
|
||||
/* $OpenBSD: buffer.c,v 1.35 2014/02/02 03:44:31 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@ -49,7 +49,7 @@ void
|
||||
buffer_free(Buffer *buffer)
|
||||
{
|
||||
if (buffer->alloc > 0) {
|
||||
memset(buffer->buf, 0, buffer->alloc);
|
||||
explicit_bzero(buffer->buf, buffer->alloc);
|
||||
buffer->alloc = 0;
|
||||
free(buffer->buf);
|
||||
}
|
||||
|
@ -192,7 +192,7 @@ ipv64_normalise_mapped(struct sockaddr_storage *addr, socklen_t *len)
|
||||
memcpy(&inaddr, ((char *)&a6->sin6_addr) + 12, sizeof(inaddr));
|
||||
port = a6->sin6_port;
|
||||
|
||||
bzero(a4, sizeof(*a4));
|
||||
memset(a4, 0, sizeof(*a4));
|
||||
|
||||
a4->sin_family = AF_INET;
|
||||
*len = sizeof(*a4);
|
||||
|
15
channels.c
15
channels.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: channels.c,v 1.328 2013/12/19 01:04:36 djm Exp $ */
|
||||
/* $OpenBSD: channels.c,v 1.331 2014/02/26 20:29:29 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@ -423,7 +423,7 @@ channel_free(Channel *c)
|
||||
if (cc->abandon_cb != NULL)
|
||||
cc->abandon_cb(c, cc->ctx);
|
||||
TAILQ_REMOVE(&c->status_confirms, cc, entry);
|
||||
bzero(cc, sizeof(*cc));
|
||||
explicit_bzero(cc, sizeof(*cc));
|
||||
free(cc);
|
||||
}
|
||||
if (c->filter_cleanup != NULL && c->filter_ctx != NULL)
|
||||
@ -1072,6 +1072,9 @@ channel_decode_socks4(Channel *c, fd_set *readset, fd_set *writeset)
|
||||
buffer_get(&c->input, (char *)&s4_req.dest_addr, 4);
|
||||
have = buffer_len(&c->input);
|
||||
p = buffer_ptr(&c->input);
|
||||
if (memchr(p, '\0', have) == NULL)
|
||||
fatal("channel %d: decode socks4: user not nul terminated",
|
||||
c->self);
|
||||
len = strlen(p);
|
||||
debug2("channel %d: decode socks4: user %s/%d", c->self, p, len);
|
||||
len++; /* trailing '\0' */
|
||||
@ -1386,7 +1389,7 @@ port_open_helper(Channel *c, char *rtype)
|
||||
int direct;
|
||||
char buf[1024];
|
||||
char *local_ipaddr = get_local_ipaddr(c->sock);
|
||||
int local_port = get_sock_port(c->sock, 1);
|
||||
int local_port = c->sock == -1 ? 65536 : get_sock_port(c->sock, 1);
|
||||
char *remote_ipaddr = get_peer_ipaddr(c->sock);
|
||||
int remote_port = get_peer_port(c->sock);
|
||||
|
||||
@ -2671,7 +2674,7 @@ channel_input_status_confirm(int type, u_int32_t seq, void *ctxt)
|
||||
return;
|
||||
cc->cb(type, c, cc->ctx);
|
||||
TAILQ_REMOVE(&c->status_confirms, cc, entry);
|
||||
bzero(cc, sizeof(*cc));
|
||||
explicit_bzero(cc, sizeof(*cc));
|
||||
free(cc);
|
||||
}
|
||||
|
||||
@ -3304,9 +3307,7 @@ channel_connect_ctx_free(struct channel_connect *cctx)
|
||||
free(cctx->host);
|
||||
if (cctx->aitop)
|
||||
freeaddrinfo(cctx->aitop);
|
||||
bzero(cctx, sizeof(*cctx));
|
||||
cctx->host = NULL;
|
||||
cctx->ai = cctx->aitop = NULL;
|
||||
memset(cctx, 0, sizeof(*cctx));
|
||||
}
|
||||
|
||||
/* Return CONNECTING channel to remote host, port */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: cipher-3des1.c,v 1.9 2013/11/08 00:39:15 djm Exp $ */
|
||||
/* $OpenBSD: cipher-3des1.c,v 1.10 2014/02/02 03:44:31 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2003 Markus Friedl. All rights reserved.
|
||||
*
|
||||
@ -93,7 +93,7 @@ ssh1_3des_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv,
|
||||
if (EVP_CipherInit(&c->k1, EVP_des_cbc(), k1, NULL, enc) == 0 ||
|
||||
EVP_CipherInit(&c->k2, EVP_des_cbc(), k2, NULL, !enc) == 0 ||
|
||||
EVP_CipherInit(&c->k3, EVP_des_cbc(), k3, NULL, enc) == 0) {
|
||||
memset(c, 0, sizeof(*c));
|
||||
explicit_bzero(c, sizeof(*c));
|
||||
free(c);
|
||||
EVP_CIPHER_CTX_set_app_data(ctx, NULL);
|
||||
return (0);
|
||||
@ -134,7 +134,7 @@ ssh1_3des_cleanup(EVP_CIPHER_CTX *ctx)
|
||||
EVP_CIPHER_CTX_cleanup(&c->k1);
|
||||
EVP_CIPHER_CTX_cleanup(&c->k2);
|
||||
EVP_CIPHER_CTX_cleanup(&c->k3);
|
||||
memset(c, 0, sizeof(*c));
|
||||
explicit_bzero(c, sizeof(*c));
|
||||
free(c);
|
||||
EVP_CIPHER_CTX_set_app_data(ctx, NULL);
|
||||
}
|
||||
|
@ -14,7 +14,7 @@
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $OpenBSD: cipher-chachapoly.c,v 1.3 2013/12/15 21:42:35 djm Exp $ */
|
||||
/* $OpenBSD: cipher-chachapoly.c,v 1.4 2014/01/31 16:39:19 tedu Exp $ */
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
@ -58,7 +58,7 @@ chachapoly_crypt(struct chachapoly_ctx *ctx, u_int seqnr, u_char *dest,
|
||||
* Run ChaCha20 once to generate the Poly1305 key. The IV is the
|
||||
* packet sequence number.
|
||||
*/
|
||||
bzero(poly_key, sizeof(poly_key));
|
||||
memset(poly_key, 0, sizeof(poly_key));
|
||||
put_u64(seqbuf, seqnr);
|
||||
chacha_ivsetup(&ctx->main_ctx, seqbuf, NULL);
|
||||
chacha_encrypt_bytes(&ctx->main_ctx,
|
||||
@ -90,9 +90,9 @@ chachapoly_crypt(struct chachapoly_ctx *ctx, u_int seqnr, u_char *dest,
|
||||
r = 0;
|
||||
|
||||
out:
|
||||
bzero(expected_tag, sizeof(expected_tag));
|
||||
bzero(seqbuf, sizeof(seqbuf));
|
||||
bzero(poly_key, sizeof(poly_key));
|
||||
explicit_bzero(expected_tag, sizeof(expected_tag));
|
||||
explicit_bzero(seqbuf, sizeof(seqbuf));
|
||||
explicit_bzero(poly_key, sizeof(poly_key));
|
||||
return r;
|
||||
}
|
||||
|
||||
|
22
cipher.c
22
cipher.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: cipher.c,v 1.94 2014/01/25 10:12:50 dtucker Exp $ */
|
||||
/* $OpenBSD: cipher.c,v 1.97 2014/02/07 06:55:54 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@ -39,8 +39,6 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <openssl/md5.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
@ -49,6 +47,8 @@
|
||||
#include "log.h"
|
||||
#include "misc.h"
|
||||
#include "cipher.h"
|
||||
#include "buffer.h"
|
||||
#include "digest.h"
|
||||
|
||||
/* compatibility with old or broken OpenSSL versions */
|
||||
#include "openbsd-compat/openssl-compat.h"
|
||||
@ -228,8 +228,6 @@ ciphers_valid(const char *names)
|
||||
debug("bad cipher %s [%s]", p, names);
|
||||
free(cipher_list);
|
||||
return 0;
|
||||
} else {
|
||||
debug3("cipher ok: %s [%s]", p, names);
|
||||
}
|
||||
}
|
||||
debug3("ciphers ok: [%s]", names);
|
||||
@ -337,7 +335,7 @@ cipher_init(CipherContext *cc, const Cipher *cipher,
|
||||
if (EVP_Cipher(&cc->evp, discard, junk,
|
||||
cipher->discard_len) == 0)
|
||||
fatal("evp_crypt: EVP_Cipher failed during discard");
|
||||
memset(discard, 0, cipher->discard_len);
|
||||
explicit_bzero(discard, cipher->discard_len);
|
||||
free(junk);
|
||||
free(discard);
|
||||
}
|
||||
@ -422,7 +420,7 @@ void
|
||||
cipher_cleanup(CipherContext *cc)
|
||||
{
|
||||
if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0)
|
||||
memset(&cc->cp_ctx, 0, sizeof(cc->cp_ctx));
|
||||
explicit_bzero(&cc->cp_ctx, sizeof(cc->cp_ctx));
|
||||
else if (EVP_CIPHER_CTX_cleanup(&cc->evp) == 0)
|
||||
error("cipher_cleanup: EVP_CIPHER_CTX_cleanup failed");
|
||||
}
|
||||
@ -436,17 +434,15 @@ void
|
||||
cipher_set_key_string(CipherContext *cc, const Cipher *cipher,
|
||||
const char *passphrase, int do_encrypt)
|
||||
{
|
||||
MD5_CTX md;
|
||||
u_char digest[16];
|
||||
|
||||
MD5_Init(&md);
|
||||
MD5_Update(&md, (const u_char *)passphrase, strlen(passphrase));
|
||||
MD5_Final(digest, &md);
|
||||
if (ssh_digest_memory(SSH_DIGEST_MD5, passphrase, strlen(passphrase),
|
||||
digest, sizeof(digest)) < 0)
|
||||
fatal("%s: md5 failed", __func__);
|
||||
|
||||
cipher_init(cc, cipher, digest, 16, NULL, 0, do_encrypt);
|
||||
|
||||
memset(digest, 0, sizeof(digest));
|
||||
memset(&md, 0, sizeof(md));
|
||||
explicit_bzero(digest, sizeof(digest));
|
||||
}
|
||||
|
||||
/*
|
||||
|
10
clientloop.c
10
clientloop.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: clientloop.c,v 1.256 2013/11/20 20:54:10 deraadt Exp $ */
|
||||
/* $OpenBSD: clientloop.c,v 1.258 2014/02/02 03:44:31 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@ -549,7 +549,7 @@ client_global_request_reply(int type, u_int32_t seq, void *ctxt)
|
||||
gc->cb(type, seq, gc->ctx);
|
||||
if (--gc->ref_count <= 0) {
|
||||
TAILQ_REMOVE(&global_confirms, gc, entry);
|
||||
bzero(gc, sizeof(*gc));
|
||||
explicit_bzero(gc, sizeof(*gc));
|
||||
free(gc);
|
||||
}
|
||||
|
||||
@ -876,7 +876,7 @@ process_cmdline(void)
|
||||
int cancel_port, ok;
|
||||
Forward fwd;
|
||||
|
||||
bzero(&fwd, sizeof(fwd));
|
||||
memset(&fwd, 0, sizeof(fwd));
|
||||
fwd.listen_host = fwd.connect_host = NULL;
|
||||
|
||||
leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE);
|
||||
@ -1761,7 +1761,7 @@ client_input_stdout_data(int type, u_int32_t seq, void *ctxt)
|
||||
char *data = packet_get_string(&data_len);
|
||||
packet_check_eom();
|
||||
buffer_append(&stdout_buffer, data, data_len);
|
||||
memset(data, 0, data_len);
|
||||
explicit_bzero(data, data_len);
|
||||
free(data);
|
||||
}
|
||||
static void
|
||||
@ -1771,7 +1771,7 @@ client_input_stderr_data(int type, u_int32_t seq, void *ctxt)
|
||||
char *data = packet_get_string(&data_len);
|
||||
packet_check_eom();
|
||||
buffer_append(&stderr_buffer, data, data_len);
|
||||
memset(data, 0, data_len);
|
||||
explicit_bzero(data, data_len);
|
||||
free(data);
|
||||
}
|
||||
static void
|
||||
|
@ -414,6 +414,9 @@
|
||||
/* Define to 1 if you have the `EVP_MD_CTX_cleanup' function. */
|
||||
#undef HAVE_EVP_MD_CTX_CLEANUP
|
||||
|
||||
/* Define to 1 if you have the `EVP_MD_CTX_copy_ex' function. */
|
||||
#undef HAVE_EVP_MD_CTX_COPY_EX
|
||||
|
||||
/* Define to 1 if you have the `EVP_MD_CTX_init' function. */
|
||||
#undef HAVE_EVP_MD_CTX_INIT
|
||||
|
||||
@ -423,6 +426,9 @@
|
||||
/* Define if you have ut_exit in utmp.h */
|
||||
#undef HAVE_EXIT_IN_UTMP
|
||||
|
||||
/* Define to 1 if you have the `explicit_bzero' function. */
|
||||
#undef HAVE_EXPLICIT_BZERO
|
||||
|
||||
/* Define to 1 if you have the `fchmod' function. */
|
||||
#undef HAVE_FCHMOD
|
||||
|
||||
|
6
configure
vendored
6
configure
vendored
@ -1,5 +1,5 @@
|
||||
#! /bin/sh
|
||||
# From configure.ac Revision: 1.568 .
|
||||
# From configure.ac Revision: 1.571 .
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.68 for OpenSSH Portable.
|
||||
#
|
||||
@ -7607,7 +7607,7 @@ $as_echo "#define BROKEN_STRNVIS 1" >>confdefs.h
|
||||
# and will crash if they cannot be opened.
|
||||
|
||||
$as_echo "#define SANDBOX_SKIP_RLIMIT_NOFILE 1" >>confdefs.h
|
||||
],
|
||||
|
||||
;;
|
||||
*-*-bsdi*)
|
||||
$as_echo "#define SETEUID_BREAKS_SETUID 1" >>confdefs.h
|
||||
@ -10366,6 +10366,7 @@ for ac_func in \
|
||||
closefrom \
|
||||
dirfd \
|
||||
endgrent \
|
||||
explicit_bzero \
|
||||
fchmod \
|
||||
fchown \
|
||||
freeaddrinfo \
|
||||
@ -12113,6 +12114,7 @@ for ac_func in \
|
||||
EVP_DigestFinal_ex \
|
||||
EVP_MD_CTX_init \
|
||||
EVP_MD_CTX_cleanup \
|
||||
EVP_MD_CTX_copy_ex \
|
||||
HMAC_CTX_init \
|
||||
RSA_generate_key_ex \
|
||||
RSA_get_default_method \
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $Id: configure.ac,v 1.568 2014/01/30 00:26:46 djm Exp $
|
||||
# $Id: configure.ac,v 1.571 2014/02/21 17:09:34 tim Exp $
|
||||
#
|
||||
# Copyright (c) 1999-2004 Damien Miller
|
||||
#
|
||||
@ -15,7 +15,7 @@
|
||||
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
AC_INIT([OpenSSH], [Portable], [openssh-unix-dev@mindrot.org])
|
||||
AC_REVISION($Revision: 1.568 $)
|
||||
AC_REVISION($Revision: 1.571 $)
|
||||
AC_CONFIG_SRCDIR([ssh.c])
|
||||
AC_LANG([C])
|
||||
|
||||
@ -785,7 +785,7 @@ mips-sony-bsd|mips-sony-newsos4)
|
||||
# Preauth crypto occasionally uses file descriptors for crypto offload
|
||||
# and will crash if they cannot be opened.
|
||||
AC_DEFINE([SANDBOX_SKIP_RLIMIT_NOFILE], [1],
|
||||
[define if setrlimit RLIMIT_NOFILE breaks things])],
|
||||
[define if setrlimit RLIMIT_NOFILE breaks things])
|
||||
;;
|
||||
*-*-bsdi*)
|
||||
AC_DEFINE([SETEUID_BREAKS_SETUID])
|
||||
@ -1649,6 +1649,7 @@ AC_CHECK_FUNCS([ \
|
||||
closefrom \
|
||||
dirfd \
|
||||
endgrent \
|
||||
explicit_bzero \
|
||||
fchmod \
|
||||
fchown \
|
||||
freeaddrinfo \
|
||||
@ -2429,6 +2430,7 @@ AC_CHECK_FUNCS([ \
|
||||
EVP_DigestFinal_ex \
|
||||
EVP_MD_CTX_init \
|
||||
EVP_MD_CTX_cleanup \
|
||||
EVP_MD_CTX_copy_ex \
|
||||
HMAC_CTX_init \
|
||||
RSA_generate_key_ex \
|
||||
RSA_get_default_method \
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
#old cvs stuff. please update before use. may be deprecated.
|
||||
%define use_stable 1
|
||||
%define version 6.5p1
|
||||
%define version 6.6p1
|
||||
%if %{use_stable}
|
||||
%define cvs %{nil}
|
||||
%define release 1
|
||||
@ -363,4 +363,4 @@ fi
|
||||
* Mon Jan 01 1998 ...
|
||||
Template Version: 1.31
|
||||
|
||||
$Id: openssh.spec,v 1.82 2014/01/16 07:51:10 djm Exp $
|
||||
$Id: openssh.spec,v 1.83 2014/02/27 23:03:55 djm Exp $
|
||||
|
@ -1,4 +1,4 @@
|
||||
%define ver 6.5p1
|
||||
%define ver 6.6p1
|
||||
%define rel 1
|
||||
|
||||
# OpenSSH privilege separation requires a user & group ID
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
Summary: OpenSSH, a free Secure Shell (SSH) protocol implementation
|
||||
Name: openssh
|
||||
Version: 6.5p1
|
||||
Version: 6.6p1
|
||||
URL: http://www.openssh.com/
|
||||
Release: 1
|
||||
Source0: openssh-%{version}.tar.gz
|
||||
|
238
digest-libc.c
Normal file
238
digest-libc.c
Normal file
@ -0,0 +1,238 @@
|
||||
/* $OpenBSD: digest-libc.c,v 1.2 2014/02/02 03:44:31 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2013 Damien Miller <djm@mindrot.org>
|
||||
* Copyright (c) 2014 Markus Friedl. 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.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <md5.h>
|
||||
#include <rmd160.h>
|
||||
#include <sha1.h>
|
||||
#include <sha2.h>
|
||||
|
||||
#include "buffer.h"
|
||||
#include "digest.h"
|
||||
|
||||
typedef void md_init_fn(void *mdctx);
|
||||
typedef void md_update_fn(void *mdctx, const u_int8_t *m, size_t mlen);
|
||||
typedef void md_final_fn(u_int8_t[], void *mdctx);
|
||||
|
||||
struct ssh_digest_ctx {
|
||||
int alg;
|
||||
void *mdctx;
|
||||
};
|
||||
|
||||
struct ssh_digest {
|
||||
int id;
|
||||
const char *name;
|
||||
size_t block_len;
|
||||
size_t digest_len;
|
||||
size_t ctx_len;
|
||||
md_init_fn *md_init;
|
||||
md_update_fn *md_update;
|
||||
md_final_fn *md_final;
|
||||
};
|
||||
|
||||
/* NB. Indexed directly by algorithm number */
|
||||
const struct ssh_digest digests[SSH_DIGEST_MAX] = {
|
||||
{
|
||||
SSH_DIGEST_MD5,
|
||||
"MD5",
|
||||
MD5_BLOCK_LENGTH,
|
||||
MD5_DIGEST_LENGTH,
|
||||
sizeof(MD5_CTX),
|
||||
(md_init_fn *) MD5Init,
|
||||
(md_update_fn *) MD5Update,
|
||||
(md_final_fn *) MD5Final
|
||||
},
|
||||
{
|
||||
SSH_DIGEST_RIPEMD160,
|
||||
"RIPEMD160",
|
||||
RMD160_BLOCK_LENGTH,
|
||||
RMD160_DIGEST_LENGTH,
|
||||
sizeof(RMD160_CTX),
|
||||
(md_init_fn *) RMD160Init,
|
||||
(md_update_fn *) RMD160Update,
|
||||
(md_final_fn *) RMD160Final
|
||||
},
|
||||
{
|
||||
SSH_DIGEST_SHA1,
|
||||
"SHA1",
|
||||
SHA1_BLOCK_LENGTH,
|
||||
SHA1_DIGEST_LENGTH,
|
||||
sizeof(SHA1_CTX),
|
||||
(md_init_fn *) SHA1Init,
|
||||
(md_update_fn *) SHA1Update,
|
||||
(md_final_fn *) SHA1Final
|
||||
},
|
||||
{
|
||||
SSH_DIGEST_SHA256,
|
||||
"SHA256",
|
||||
SHA256_BLOCK_LENGTH,
|
||||
SHA256_DIGEST_LENGTH,
|
||||
sizeof(SHA2_CTX),
|
||||
(md_init_fn *) SHA256Init,
|
||||
(md_update_fn *) SHA256Update,
|
||||
(md_final_fn *) SHA256Final
|
||||
},
|
||||
{
|
||||
SSH_DIGEST_SHA384,
|
||||
"SHA384",
|
||||
SHA384_BLOCK_LENGTH,
|
||||
SHA384_DIGEST_LENGTH,
|
||||
sizeof(SHA2_CTX),
|
||||
(md_init_fn *) SHA384Init,
|
||||
(md_update_fn *) SHA384Update,
|
||||
(md_final_fn *) SHA384Final
|
||||
},
|
||||
{
|
||||
SSH_DIGEST_SHA512,
|
||||
"SHA512",
|
||||
SHA512_BLOCK_LENGTH,
|
||||
SHA512_DIGEST_LENGTH,
|
||||
sizeof(SHA2_CTX),
|
||||
(md_init_fn *) SHA512Init,
|
||||
(md_update_fn *) SHA512Update,
|
||||
(md_final_fn *) SHA512Final
|
||||
}
|
||||
};
|
||||
|
||||
static const struct ssh_digest *
|
||||
ssh_digest_by_alg(int alg)
|
||||
{
|
||||
if (alg < 0 || alg >= SSH_DIGEST_MAX)
|
||||
return NULL;
|
||||
if (digests[alg].id != alg) /* sanity */
|
||||
return NULL;
|
||||
return &(digests[alg]);
|
||||
}
|
||||
|
||||
size_t
|
||||
ssh_digest_bytes(int alg)
|
||||
{
|
||||
const struct ssh_digest *digest = ssh_digest_by_alg(alg);
|
||||
|
||||
return digest == NULL ? 0 : digest->digest_len;
|
||||
}
|
||||
|
||||
size_t
|
||||
ssh_digest_blocksize(struct ssh_digest_ctx *ctx)
|
||||
{
|
||||
const struct ssh_digest *digest = ssh_digest_by_alg(ctx->alg);
|
||||
|
||||
return digest == NULL ? 0 : digest->block_len;
|
||||
}
|
||||
|
||||
struct ssh_digest_ctx *
|
||||
ssh_digest_start(int alg)
|
||||
{
|
||||
const struct ssh_digest *digest = ssh_digest_by_alg(alg);
|
||||
struct ssh_digest_ctx *ret;
|
||||
|
||||
if (digest == NULL || (ret = calloc(1, sizeof(ret))) == NULL)
|
||||
return NULL;
|
||||
if ((ret->mdctx = calloc(1, digest->ctx_len)) == NULL) {
|
||||
free(ret);
|
||||
return NULL;
|
||||
}
|
||||
ret->alg = alg;
|
||||
digest->md_init(ret->mdctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
ssh_digest_copy_state(struct ssh_digest_ctx *from, struct ssh_digest_ctx *to)
|
||||
{
|
||||
const struct ssh_digest *digest = ssh_digest_by_alg(from->alg);
|
||||
|
||||
if (digest == NULL || from->alg != to->alg)
|
||||
return -1;
|
||||
memcpy(to->mdctx, from->mdctx, digest->ctx_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ssh_digest_update(struct ssh_digest_ctx *ctx, const void *m, size_t mlen)
|
||||
{
|
||||
const struct ssh_digest *digest = ssh_digest_by_alg(ctx->alg);
|
||||
|
||||
if (digest == NULL)
|
||||
return -1;
|
||||
digest->md_update(ctx->mdctx, m, mlen);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ssh_digest_update_buffer(struct ssh_digest_ctx *ctx, const Buffer *b)
|
||||
{
|
||||
return ssh_digest_update(ctx, buffer_ptr(b), buffer_len(b));
|
||||
}
|
||||
|
||||
int
|
||||
ssh_digest_final(struct ssh_digest_ctx *ctx, u_char *d, size_t dlen)
|
||||
{
|
||||
const struct ssh_digest *digest = ssh_digest_by_alg(ctx->alg);
|
||||
|
||||
if (digest == NULL)
|
||||
return -1;
|
||||
if (dlen > UINT_MAX)
|
||||
return -1;
|
||||
if (dlen < digest->digest_len) /* No truncation allowed */
|
||||
return -1;
|
||||
digest->md_final(d, ctx->mdctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
ssh_digest_free(struct ssh_digest_ctx *ctx)
|
||||
{
|
||||
const struct ssh_digest *digest;
|
||||
|
||||
if (ctx != NULL) {
|
||||
digest = ssh_digest_by_alg(ctx->alg);
|
||||
if (digest) {
|
||||
explicit_bzero(ctx->mdctx, digest->ctx_len);
|
||||
free(ctx->mdctx);
|
||||
explicit_bzero(ctx, sizeof(*ctx));
|
||||
free(ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
ssh_digest_memory(int alg, const void *m, size_t mlen, u_char *d, size_t dlen)
|
||||
{
|
||||
struct ssh_digest_ctx *ctx = ssh_digest_start(alg);
|
||||
|
||||
if (ctx == NULL)
|
||||
return -1;
|
||||
if (ssh_digest_update(ctx, m, mlen) != 0 ||
|
||||
ssh_digest_final(ctx, d, dlen) != 0)
|
||||
return -1;
|
||||
ssh_digest_free(ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ssh_digest_buffer(int alg, const Buffer *b, u_char *d, size_t dlen)
|
||||
{
|
||||
return ssh_digest_memory(alg, buffer_ptr(b), buffer_len(b), d, dlen);
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: digest.c,v 1.3 2014/01/20 00:08:48 djm Exp $ */
|
||||
/* $OpenBSD: digest-openssl.c,v 1.2 2014/02/02 03:44:31 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2013 Damien Miller <djm@mindrot.org>
|
||||
*
|
||||
@ -72,6 +72,12 @@ ssh_digest_bytes(int alg)
|
||||
return digest == NULL ? 0 : digest->digest_len;
|
||||
}
|
||||
|
||||
size_t
|
||||
ssh_digest_blocksize(struct ssh_digest_ctx *ctx)
|
||||
{
|
||||
return EVP_MD_CTX_block_size(&ctx->mdctx);
|
||||
}
|
||||
|
||||
struct ssh_digest_ctx *
|
||||
ssh_digest_start(int alg)
|
||||
{
|
||||
@ -89,6 +95,15 @@ ssh_digest_start(int alg)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
ssh_digest_copy_state(struct ssh_digest_ctx *from, struct ssh_digest_ctx *to)
|
||||
{
|
||||
/* we have bcopy-style order while openssl has memcpy-style */
|
||||
if (!EVP_MD_CTX_copy_ex(&to->mdctx, &from->mdctx))
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ssh_digest_update(struct ssh_digest_ctx *ctx, const void *m, size_t mlen)
|
||||
{
|
||||
@ -123,9 +138,11 @@ ssh_digest_final(struct ssh_digest_ctx *ctx, u_char *d, size_t dlen)
|
||||
void
|
||||
ssh_digest_free(struct ssh_digest_ctx *ctx)
|
||||
{
|
||||
EVP_MD_CTX_cleanup(&ctx->mdctx);
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
free(ctx);
|
||||
if (ctx != NULL) {
|
||||
EVP_MD_CTX_cleanup(&ctx->mdctx);
|
||||
explicit_bzero(ctx, sizeof(*ctx));
|
||||
free(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
12
digest.h
12
digest.h
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: digest.h,v 1.1 2014/01/09 23:20:00 djm Exp $ */
|
||||
/* $OpenBSD: digest.h,v 1.2 2014/01/27 18:58:14 markus Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2013 Damien Miller <djm@mindrot.org>
|
||||
*
|
||||
@ -30,9 +30,18 @@
|
||||
#define SSH_DIGEST_SHA512 5
|
||||
#define SSH_DIGEST_MAX 6
|
||||
|
||||
struct ssh_digest_ctx;
|
||||
|
||||
/* Returns the algorithm's digest length in bytes or 0 for invalid algorithm */
|
||||
size_t ssh_digest_bytes(int alg);
|
||||
|
||||
/* Returns the block size of the digest, e.g. for implementing HMAC */
|
||||
size_t ssh_digest_blocksize(struct ssh_digest_ctx *ctx);
|
||||
|
||||
/* Copies internal state of digest of 'from' to 'to' */
|
||||
int ssh_digest_copy_state(struct ssh_digest_ctx *from,
|
||||
struct ssh_digest_ctx *to);
|
||||
|
||||
/* One-shot API */
|
||||
int ssh_digest_memory(int alg, const void *m, size_t mlen,
|
||||
u_char *d, size_t dlen)
|
||||
@ -42,7 +51,6 @@ int ssh_digest_buffer(int alg, const Buffer *b, u_char *d, size_t dlen)
|
||||
__attribute__((__bounded__(__buffer__, 3, 4)));
|
||||
|
||||
/* Update API */
|
||||
struct ssh_digest_ctx;
|
||||
struct ssh_digest_ctx *ssh_digest_start(int alg);
|
||||
int ssh_digest_update(struct ssh_digest_ctx *ctx, const void *m, size_t mlen)
|
||||
__attribute__((__bounded__(__buffer__, 2, 3)));
|
||||
|
24
gss-serv.c
24
gss-serv.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: gss-serv.c,v 1.24 2013/07/20 01:55:13 djm Exp $ */
|
||||
/* $OpenBSD: gss-serv.c,v 1.26 2014/02/26 20:28:44 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
|
||||
@ -66,6 +66,25 @@ ssh_gssapi_mech* supported_mechs[]= {
|
||||
&gssapi_null_mech,
|
||||
};
|
||||
|
||||
/*
|
||||
* ssh_gssapi_supported_oids() can cause sandbox violations, so prepare the
|
||||
* list of supported mechanisms before privsep is set up.
|
||||
*/
|
||||
static gss_OID_set supported_oids;
|
||||
|
||||
void
|
||||
ssh_gssapi_prepare_supported_oids(void)
|
||||
{
|
||||
ssh_gssapi_supported_oids(&supported_oids);
|
||||
}
|
||||
|
||||
OM_uint32
|
||||
ssh_gssapi_test_oid_supported(OM_uint32 *ms, gss_OID member, int *present)
|
||||
{
|
||||
if (supported_oids == NULL)
|
||||
ssh_gssapi_prepare_supported_oids();
|
||||
return gss_test_oid_set_member(ms, member, supported_oids, present);
|
||||
}
|
||||
|
||||
/*
|
||||
* Acquire credentials for a server running on the current host.
|
||||
@ -346,7 +365,8 @@ ssh_gssapi_userok(char *user)
|
||||
gss_release_buffer(&lmin, &gssapi_client.displayname);
|
||||
gss_release_buffer(&lmin, &gssapi_client.exportedname);
|
||||
gss_release_cred(&lmin, &gssapi_client.creds);
|
||||
memset(&gssapi_client, 0, sizeof(ssh_gssapi_client));
|
||||
explicit_bzero(&gssapi_client,
|
||||
sizeof(ssh_gssapi_client));
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
|
197
hmac.c
Normal file
197
hmac.c
Normal file
@ -0,0 +1,197 @@
|
||||
/* $OpenBSD: hmac.c,v 1.10 2014/01/31 16:39:19 tedu Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2014 Markus Friedl. 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.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "buffer.h"
|
||||
#include "digest.h"
|
||||
#include "hmac.h"
|
||||
|
||||
struct ssh_hmac_ctx {
|
||||
int alg;
|
||||
struct ssh_digest_ctx *ictx;
|
||||
struct ssh_digest_ctx *octx;
|
||||
struct ssh_digest_ctx *digest;
|
||||
u_char *buf;
|
||||
size_t buf_len;
|
||||
};
|
||||
|
||||
size_t
|
||||
ssh_hmac_bytes(int alg)
|
||||
{
|
||||
return ssh_digest_bytes(alg);
|
||||
}
|
||||
|
||||
struct ssh_hmac_ctx *
|
||||
ssh_hmac_start(int alg)
|
||||
{
|
||||
struct ssh_hmac_ctx *ret;
|
||||
|
||||
if ((ret = calloc(1, sizeof(*ret))) == NULL)
|
||||
return NULL;
|
||||
ret->alg = alg;
|
||||
if ((ret->ictx = ssh_digest_start(alg)) == NULL ||
|
||||
(ret->octx = ssh_digest_start(alg)) == NULL ||
|
||||
(ret->digest = ssh_digest_start(alg)) == NULL)
|
||||
goto fail;
|
||||
ret->buf_len = ssh_digest_blocksize(ret->ictx);
|
||||
if ((ret->buf = calloc(1, ret->buf_len)) == NULL)
|
||||
goto fail;
|
||||
return ret;
|
||||
fail:
|
||||
ssh_hmac_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
ssh_hmac_init(struct ssh_hmac_ctx *ctx, const void *key, size_t klen)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
/* reset ictx and octx if no is key given */
|
||||
if (key != NULL) {
|
||||
/* truncate long keys */
|
||||
if (klen <= ctx->buf_len)
|
||||
memcpy(ctx->buf, key, klen);
|
||||
else if (ssh_digest_memory(ctx->alg, key, klen, ctx->buf,
|
||||
ctx->buf_len) < 0)
|
||||
return -1;
|
||||
for (i = 0; i < ctx->buf_len; i++)
|
||||
ctx->buf[i] ^= 0x36;
|
||||
if (ssh_digest_update(ctx->ictx, ctx->buf, ctx->buf_len) < 0)
|
||||
return -1;
|
||||
for (i = 0; i < ctx->buf_len; i++)
|
||||
ctx->buf[i] ^= 0x36 ^ 0x5c;
|
||||
if (ssh_digest_update(ctx->octx, ctx->buf, ctx->buf_len) < 0)
|
||||
return -1;
|
||||
explicit_bzero(ctx->buf, ctx->buf_len);
|
||||
}
|
||||
/* start with ictx */
|
||||
if (ssh_digest_copy_state(ctx->ictx, ctx->digest) < 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ssh_hmac_update(struct ssh_hmac_ctx *ctx, const void *m, size_t mlen)
|
||||
{
|
||||
return ssh_digest_update(ctx->digest, m, mlen);
|
||||
}
|
||||
|
||||
int
|
||||
ssh_hmac_update_buffer(struct ssh_hmac_ctx *ctx, const Buffer *b)
|
||||
{
|
||||
return ssh_digest_update_buffer(ctx->digest, b);
|
||||
}
|
||||
|
||||
int
|
||||
ssh_hmac_final(struct ssh_hmac_ctx *ctx, u_char *d, size_t dlen)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
len = ssh_digest_bytes(ctx->alg);
|
||||
if (dlen < len ||
|
||||
ssh_digest_final(ctx->digest, ctx->buf, len))
|
||||
return -1;
|
||||
/* switch to octx */
|
||||
if (ssh_digest_copy_state(ctx->octx, ctx->digest) < 0 ||
|
||||
ssh_digest_update(ctx->digest, ctx->buf, len) < 0 ||
|
||||
ssh_digest_final(ctx->digest, d, dlen) < 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
ssh_hmac_free(struct ssh_hmac_ctx *ctx)
|
||||
{
|
||||
if (ctx != NULL) {
|
||||
ssh_digest_free(ctx->ictx);
|
||||
ssh_digest_free(ctx->octx);
|
||||
ssh_digest_free(ctx->digest);
|
||||
if (ctx->buf) {
|
||||
explicit_bzero(ctx->buf, ctx->buf_len);
|
||||
free(ctx->buf);
|
||||
}
|
||||
explicit_bzero(ctx, sizeof(*ctx));
|
||||
free(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
/* cc -DTEST hmac.c digest.c buffer.c cleanup.c fatal.c log.c xmalloc.c -lcrypto */
|
||||
static void
|
||||
hmac_test(void *key, size_t klen, void *m, size_t mlen, u_char *e, size_t elen)
|
||||
{
|
||||
struct ssh_hmac_ctx *ctx;
|
||||
size_t i;
|
||||
u_char digest[16];
|
||||
|
||||
if ((ctx = ssh_hmac_start(SSH_DIGEST_MD5)) == NULL)
|
||||
printf("ssh_hmac_start failed");
|
||||
if (ssh_hmac_init(ctx, key, klen) < 0 ||
|
||||
ssh_hmac_update(ctx, m, mlen) < 0 ||
|
||||
ssh_hmac_final(ctx, digest, sizeof(digest)) < 0)
|
||||
printf("ssh_hmac_xxx failed");
|
||||
ssh_hmac_free(ctx);
|
||||
|
||||
if (memcmp(e, digest, elen)) {
|
||||
for (i = 0; i < elen; i++)
|
||||
printf("[%zd] %2.2x %2.2x\n", i, e[i], digest[i]);
|
||||
printf("mismatch\n");
|
||||
} else
|
||||
printf("ok\n");
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
/* try test vectors from RFC 2104 */
|
||||
|
||||
u_char key1[16] = {
|
||||
0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb,
|
||||
0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb };
|
||||
u_char *data1 = "Hi There";
|
||||
u_char dig1[16] = {
|
||||
0x92, 0x94, 0x72, 0x7a, 0x36, 0x38, 0xbb, 0x1c,
|
||||
0x13, 0xf4, 0x8e, 0xf8, 0x15, 0x8b, 0xfc, 0x9d };
|
||||
|
||||
u_char *key2 = "Jefe";
|
||||
u_char *data2 = "what do ya want for nothing?";
|
||||
u_char dig2[16] = {
|
||||
0x75, 0x0c, 0x78, 0x3e, 0x6a, 0xb0, 0xb5, 0x03,
|
||||
0xea, 0xa8, 0x6e, 0x31, 0x0a, 0x5d, 0xb7, 0x38 };
|
||||
|
||||
u_char key3[16];
|
||||
u_char data3[50];
|
||||
u_char dig3[16] = {
|
||||
0x56, 0xbe, 0x34, 0x52, 0x1d, 0x14, 0x4c, 0x88,
|
||||
0xdb, 0xb8, 0xc7, 0x33, 0xf0, 0xe8, 0xb3, 0xf6 };
|
||||
memset(key3, 0xaa, sizeof(key3));
|
||||
memset(data3, 0xdd, sizeof(data3));
|
||||
|
||||
hmac_test(key1, sizeof(key1), data1, strlen(data1), dig1, sizeof(dig1));
|
||||
hmac_test(key2, strlen(key2), data2, strlen(data2), dig2, sizeof(dig2));
|
||||
hmac_test(key3, sizeof(key3), data3, sizeof(data3), dig3, sizeof(dig3));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
37
hmac.h
Normal file
37
hmac.h
Normal file
@ -0,0 +1,37 @@
|
||||
/* $OpenBSD: hmac.h,v 1.6 2014/01/27 18:58:14 markus Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2014 Markus Friedl. 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.
|
||||
*/
|
||||
|
||||
#ifndef _HMAC_H
|
||||
#define _HMAC_H
|
||||
|
||||
/* Returns the algorithm's digest length in bytes or 0 for invalid algorithm */
|
||||
size_t ssh_hmac_bytes(int alg);
|
||||
|
||||
struct ssh_hmac_ctx;
|
||||
struct ssh_hmac_ctx *ssh_hmac_start(int alg);
|
||||
|
||||
/* Sets the state of the HMAC or resets the state if key == NULL */
|
||||
int ssh_hmac_init(struct ssh_hmac_ctx *ctx, const void *key, size_t klen)
|
||||
__attribute__((__bounded__(__buffer__, 2, 3)));
|
||||
int ssh_hmac_update(struct ssh_hmac_ctx *ctx, const void *m, size_t mlen)
|
||||
__attribute__((__bounded__(__buffer__, 2, 3)));
|
||||
int ssh_hmac_update_buffer(struct ssh_hmac_ctx *ctx, const Buffer *b);
|
||||
int ssh_hmac_final(struct ssh_hmac_ctx *ctx, u_char *d, size_t dlen)
|
||||
__attribute__((__bounded__(__buffer__, 2, 3)));
|
||||
void ssh_hmac_free(struct ssh_hmac_ctx *ctx);
|
||||
|
||||
#endif /* _HMAC_H */
|
33
hostfile.c
33
hostfile.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: hostfile.c,v 1.53 2014/01/09 23:20:00 djm Exp $ */
|
||||
/* $OpenBSD: hostfile.c,v 1.55 2014/01/31 16:39:19 tedu Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@ -42,9 +42,6 @@
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/sha.h>
|
||||
|
||||
#include <resolv.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
@ -58,6 +55,7 @@
|
||||
#include "log.h"
|
||||
#include "misc.h"
|
||||
#include "digest.h"
|
||||
#include "hmac.h"
|
||||
|
||||
struct hostkeys {
|
||||
struct hostkey_entry *entries;
|
||||
@ -102,9 +100,9 @@ extract_salt(const char *s, u_int l, u_char *salt, size_t salt_len)
|
||||
debug2("extract_salt: salt decode error");
|
||||
return (-1);
|
||||
}
|
||||
if (ret != SHA_DIGEST_LENGTH) {
|
||||
debug2("extract_salt: expected salt len %d, got %d",
|
||||
SHA_DIGEST_LENGTH, ret);
|
||||
if (ret != (int)ssh_hmac_bytes(SSH_DIGEST_SHA1)) {
|
||||
debug2("extract_salt: expected salt len %zd, got %d",
|
||||
ssh_hmac_bytes(SSH_DIGEST_SHA1), ret);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
@ -114,14 +112,13 @@ extract_salt(const char *s, u_int l, u_char *salt, size_t salt_len)
|
||||
char *
|
||||
host_hash(const char *host, const char *name_from_hostfile, u_int src_len)
|
||||
{
|
||||
const EVP_MD *md = EVP_sha1();
|
||||
HMAC_CTX mac_ctx;
|
||||
struct ssh_hmac_ctx *ctx;
|
||||
u_char salt[256], result[256];
|
||||
char uu_salt[512], uu_result[512];
|
||||
static char encoded[1024];
|
||||
u_int i, len;
|
||||
|
||||
len = EVP_MD_size(md);
|
||||
len = ssh_digest_bytes(SSH_DIGEST_SHA1);
|
||||
|
||||
if (name_from_hostfile == NULL) {
|
||||
/* Create new salt */
|
||||
@ -134,14 +131,16 @@ host_hash(const char *host, const char *name_from_hostfile, u_int src_len)
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
HMAC_Init(&mac_ctx, salt, len, md);
|
||||
HMAC_Update(&mac_ctx, (u_char *)host, strlen(host));
|
||||
HMAC_Final(&mac_ctx, result, NULL);
|
||||
HMAC_cleanup(&mac_ctx);
|
||||
if ((ctx = ssh_hmac_start(SSH_DIGEST_SHA1)) == NULL ||
|
||||
ssh_hmac_init(ctx, salt, len) < 0 ||
|
||||
ssh_hmac_update(ctx, host, strlen(host)) < 0 ||
|
||||
ssh_hmac_final(ctx, result, sizeof(result)))
|
||||
fatal("%s: ssh_hmac failed", __func__);
|
||||
ssh_hmac_free(ctx);
|
||||
|
||||
if (__b64_ntop(salt, len, uu_salt, sizeof(uu_salt)) == -1 ||
|
||||
__b64_ntop(result, len, uu_result, sizeof(uu_result)) == -1)
|
||||
fatal("host_hash: __b64_ntop failed");
|
||||
fatal("%s: __b64_ntop failed", __func__);
|
||||
|
||||
snprintf(encoded, sizeof(encoded), "%s%s%c%s", HASH_MAGIC, uu_salt,
|
||||
HASH_DELIM, uu_result);
|
||||
@ -334,10 +333,10 @@ free_hostkeys(struct hostkeys *hostkeys)
|
||||
free(hostkeys->entries[i].host);
|
||||
free(hostkeys->entries[i].file);
|
||||
key_free(hostkeys->entries[i].key);
|
||||
bzero(hostkeys->entries + i, sizeof(*hostkeys->entries));
|
||||
explicit_bzero(hostkeys->entries + i, sizeof(*hostkeys->entries));
|
||||
}
|
||||
free(hostkeys->entries);
|
||||
bzero(hostkeys, sizeof(*hostkeys));
|
||||
explicit_bzero(hostkeys, sizeof(*hostkeys));
|
||||
free(hostkeys);
|
||||
}
|
||||
|
||||
|
456
jpake.c
456
jpake.c
@ -1,456 +0,0 @@
|
||||
/* $OpenBSD: jpake.c,v 1.8 2013/05/17 00:13:13 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Shared components 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
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.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 "misc.h"
|
||||
|
||||
#include "jpake.h"
|
||||
#include "schnorr.h"
|
||||
|
||||
#ifdef JPAKE
|
||||
|
||||
/* RFC3526 group 5, 1536 bits */
|
||||
#define JPAKE_GROUP_G "2"
|
||||
#define JPAKE_GROUP_P \
|
||||
"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74" \
|
||||
"020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437" \
|
||||
"4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" \
|
||||
"EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05" \
|
||||
"98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB" \
|
||||
"9ED529077096966D670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF"
|
||||
|
||||
struct modp_group *
|
||||
jpake_default_group(void)
|
||||
{
|
||||
return modp_group_from_g_and_safe_p(JPAKE_GROUP_G, JPAKE_GROUP_P);
|
||||
}
|
||||
|
||||
struct jpake_ctx *
|
||||
jpake_new(void)
|
||||
{
|
||||
struct jpake_ctx *ret;
|
||||
|
||||
ret = xcalloc(1, sizeof(*ret));
|
||||
|
||||
ret->grp = jpake_default_group();
|
||||
|
||||
ret->s = ret->k = NULL;
|
||||
ret->x1 = ret->x2 = ret->x3 = ret->x4 = NULL;
|
||||
ret->g_x1 = ret->g_x2 = ret->g_x3 = ret->g_x4 = NULL;
|
||||
ret->a = ret->b = NULL;
|
||||
|
||||
ret->client_id = ret->server_id = NULL;
|
||||
ret->h_k_cid_sessid = ret->h_k_sid_sessid = NULL;
|
||||
|
||||
debug3("%s: alloc %p", __func__, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
jpake_free(struct jpake_ctx *pctx)
|
||||
{
|
||||
debug3("%s: free %p", __func__, pctx);
|
||||
|
||||
#define JPAKE_BN_CLEAR_FREE(v) \
|
||||
do { \
|
||||
if ((v) != NULL) { \
|
||||
BN_clear_free(v); \
|
||||
(v) = NULL; \
|
||||
} \
|
||||
} while (0)
|
||||
#define JPAKE_BUF_CLEAR_FREE(v, l) \
|
||||
do { \
|
||||
if ((v) != NULL) { \
|
||||
bzero((v), (l)); \
|
||||
free(v); \
|
||||
(v) = NULL; \
|
||||
(l) = 0; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
JPAKE_BN_CLEAR_FREE(pctx->s);
|
||||
JPAKE_BN_CLEAR_FREE(pctx->k);
|
||||
JPAKE_BN_CLEAR_FREE(pctx->x1);
|
||||
JPAKE_BN_CLEAR_FREE(pctx->x2);
|
||||
JPAKE_BN_CLEAR_FREE(pctx->x3);
|
||||
JPAKE_BN_CLEAR_FREE(pctx->x4);
|
||||
JPAKE_BN_CLEAR_FREE(pctx->g_x1);
|
||||
JPAKE_BN_CLEAR_FREE(pctx->g_x2);
|
||||
JPAKE_BN_CLEAR_FREE(pctx->g_x3);
|
||||
JPAKE_BN_CLEAR_FREE(pctx->g_x4);
|
||||
JPAKE_BN_CLEAR_FREE(pctx->a);
|
||||
JPAKE_BN_CLEAR_FREE(pctx->b);
|
||||
|
||||
JPAKE_BUF_CLEAR_FREE(pctx->client_id, pctx->client_id_len);
|
||||
JPAKE_BUF_CLEAR_FREE(pctx->server_id, pctx->server_id_len);
|
||||
JPAKE_BUF_CLEAR_FREE(pctx->h_k_cid_sessid, pctx->h_k_cid_sessid_len);
|
||||
JPAKE_BUF_CLEAR_FREE(pctx->h_k_sid_sessid, pctx->h_k_sid_sessid_len);
|
||||
|
||||
#undef JPAKE_BN_CLEAR_FREE
|
||||
#undef JPAKE_BUF_CLEAR_FREE
|
||||
|
||||
bzero(pctx, sizeof(*pctx));
|
||||
free(pctx);
|
||||
}
|
||||
|
||||
/* dump entire jpake_ctx. NB. includes private values! */
|
||||
void
|
||||
jpake_dump(struct jpake_ctx *pctx, const char *fmt, ...)
|
||||
{
|
||||
char *out;
|
||||
va_list args;
|
||||
|
||||
out = NULL;
|
||||
va_start(args, fmt);
|
||||
vasprintf(&out, fmt, args);
|
||||
va_end(args);
|
||||
if (out == NULL)
|
||||
fatal("%s: vasprintf failed", __func__);
|
||||
|
||||
debug3("%s: %s (ctx at %p)", __func__, out, pctx);
|
||||
if (pctx == NULL) {
|
||||
free(out);
|
||||
return;
|
||||
}
|
||||
|
||||
#define JPAKE_DUMP_BN(a) do { \
|
||||
if ((a) != NULL) \
|
||||
JPAKE_DEBUG_BN(((a), "%s = ", #a)); \
|
||||
} while (0)
|
||||
#define JPAKE_DUMP_BUF(a, b) do { \
|
||||
if ((a) != NULL) \
|
||||
JPAKE_DEBUG_BUF((a, b, "%s", #a)); \
|
||||
} while (0)
|
||||
|
||||
JPAKE_DUMP_BN(pctx->s);
|
||||
JPAKE_DUMP_BN(pctx->k);
|
||||
JPAKE_DUMP_BN(pctx->x1);
|
||||
JPAKE_DUMP_BN(pctx->x2);
|
||||
JPAKE_DUMP_BN(pctx->x3);
|
||||
JPAKE_DUMP_BN(pctx->x4);
|
||||
JPAKE_DUMP_BN(pctx->g_x1);
|
||||
JPAKE_DUMP_BN(pctx->g_x2);
|
||||
JPAKE_DUMP_BN(pctx->g_x3);
|
||||
JPAKE_DUMP_BN(pctx->g_x4);
|
||||
JPAKE_DUMP_BN(pctx->a);
|
||||
JPAKE_DUMP_BN(pctx->b);
|
||||
|
||||
JPAKE_DUMP_BUF(pctx->client_id, pctx->client_id_len);
|
||||
JPAKE_DUMP_BUF(pctx->server_id, pctx->server_id_len);
|
||||
JPAKE_DUMP_BUF(pctx->h_k_cid_sessid, pctx->h_k_cid_sessid_len);
|
||||
JPAKE_DUMP_BUF(pctx->h_k_sid_sessid, pctx->h_k_sid_sessid_len);
|
||||
|
||||
debug3("%s: %s done", __func__, out);
|
||||
free(out);
|
||||
}
|
||||
|
||||
/* Shared parts of step 1 exchange calculation */
|
||||
void
|
||||
jpake_step1(struct modp_group *grp,
|
||||
u_char **id, u_int *id_len,
|
||||
BIGNUM **priv1, BIGNUM **priv2, BIGNUM **g_priv1, BIGNUM **g_priv2,
|
||||
u_char **priv1_proof, u_int *priv1_proof_len,
|
||||
u_char **priv2_proof, u_int *priv2_proof_len)
|
||||
{
|
||||
BN_CTX *bn_ctx;
|
||||
|
||||
if ((bn_ctx = BN_CTX_new()) == NULL)
|
||||
fatal("%s: BN_CTX_new", __func__);
|
||||
|
||||
/* Random nonce to prevent replay */
|
||||
*id = xmalloc(KZP_ID_LEN);
|
||||
*id_len = KZP_ID_LEN;
|
||||
arc4random_buf(*id, *id_len);
|
||||
|
||||
/*
|
||||
* x1/x3 is a random element of Zq
|
||||
* x2/x4 is a random element of Z*q
|
||||
* We also exclude [1] from x1/x3 candidates and [0, 1] from
|
||||
* x2/x4 candiates to avoid possible degeneracy (i.e. g^0, g^1).
|
||||
*/
|
||||
if ((*priv1 = bn_rand_range_gt_one(grp->q)) == NULL ||
|
||||
(*priv2 = bn_rand_range_gt_one(grp->q)) == NULL)
|
||||
fatal("%s: bn_rand_range_gt_one", __func__);
|
||||
|
||||
/*
|
||||
* client: g_x1 = g^x1 mod p / server: g_x3 = g^x3 mod p
|
||||
* client: g_x2 = g^x2 mod p / server: g_x4 = g^x4 mod p
|
||||
*/
|
||||
if ((*g_priv1 = BN_new()) == NULL ||
|
||||
(*g_priv2 = BN_new()) == NULL)
|
||||
fatal("%s: BN_new", __func__);
|
||||
if (BN_mod_exp(*g_priv1, grp->g, *priv1, grp->p, bn_ctx) == -1)
|
||||
fatal("%s: BN_mod_exp", __func__);
|
||||
if (BN_mod_exp(*g_priv2, grp->g, *priv2, grp->p, bn_ctx) == -1)
|
||||
fatal("%s: BN_mod_exp", __func__);
|
||||
|
||||
/* Generate proofs for holding x1/x3 and x2/x4 */
|
||||
if (schnorr_sign_buf(grp->p, grp->q, grp->g,
|
||||
*priv1, *g_priv1, *id, *id_len,
|
||||
priv1_proof, priv1_proof_len) != 0)
|
||||
fatal("%s: schnorr_sign", __func__);
|
||||
if (schnorr_sign_buf(grp->p, grp->q, grp->g,
|
||||
*priv2, *g_priv2, *id, *id_len,
|
||||
priv2_proof, priv2_proof_len) != 0)
|
||||
fatal("%s: schnorr_sign", __func__);
|
||||
|
||||
BN_CTX_free(bn_ctx);
|
||||
}
|
||||
|
||||
/* Shared parts of step 2 exchange calculation */
|
||||
void
|
||||
jpake_step2(struct modp_group *grp, BIGNUM *s,
|
||||
BIGNUM *mypub1, BIGNUM *theirpub1, BIGNUM *theirpub2, BIGNUM *mypriv2,
|
||||
const u_char *theirid, u_int theirid_len,
|
||||
const u_char *myid, u_int myid_len,
|
||||
const u_char *theirpub1_proof, u_int theirpub1_proof_len,
|
||||
const u_char *theirpub2_proof, u_int theirpub2_proof_len,
|
||||
BIGNUM **newpub,
|
||||
u_char **newpub_exponent_proof, u_int *newpub_exponent_proof_len)
|
||||
{
|
||||
BN_CTX *bn_ctx;
|
||||
BIGNUM *tmp, *exponent;
|
||||
|
||||
/* Validate peer's step 1 values */
|
||||
if (BN_cmp(theirpub1, BN_value_one()) <= 0)
|
||||
fatal("%s: theirpub1 <= 1", __func__);
|
||||
if (BN_cmp(theirpub1, grp->p) >= 0)
|
||||
fatal("%s: theirpub1 >= p", __func__);
|
||||
if (BN_cmp(theirpub2, BN_value_one()) <= 0)
|
||||
fatal("%s: theirpub2 <= 1", __func__);
|
||||
if (BN_cmp(theirpub2, grp->p) >= 0)
|
||||
fatal("%s: theirpub2 >= p", __func__);
|
||||
|
||||
if (schnorr_verify_buf(grp->p, grp->q, grp->g, theirpub1,
|
||||
theirid, theirid_len, theirpub1_proof, theirpub1_proof_len) != 1)
|
||||
fatal("%s: schnorr_verify theirpub1 failed", __func__);
|
||||
if (schnorr_verify_buf(grp->p, grp->q, grp->g, theirpub2,
|
||||
theirid, theirid_len, theirpub2_proof, theirpub2_proof_len) != 1)
|
||||
fatal("%s: schnorr_verify theirpub2 failed", __func__);
|
||||
|
||||
if ((bn_ctx = BN_CTX_new()) == NULL)
|
||||
fatal("%s: BN_CTX_new", __func__);
|
||||
|
||||
if ((*newpub = BN_new()) == NULL ||
|
||||
(tmp = BN_new()) == NULL ||
|
||||
(exponent = BN_new()) == NULL)
|
||||
fatal("%s: BN_new", __func__);
|
||||
|
||||
/*
|
||||
* client: exponent = x2 * s mod p
|
||||
* server: exponent = x4 * s mod p
|
||||
*/
|
||||
if (BN_mod_mul(exponent, mypriv2, s, grp->q, bn_ctx) != 1)
|
||||
fatal("%s: BN_mod_mul (exponent = mypriv2 * s mod p)",
|
||||
__func__);
|
||||
|
||||
/*
|
||||
* client: tmp = g^(x1 + x3 + x4) mod p
|
||||
* server: tmp = g^(x1 + x2 + x3) mod p
|
||||
*/
|
||||
if (BN_mod_mul(tmp, mypub1, theirpub1, grp->p, bn_ctx) != 1)
|
||||
fatal("%s: BN_mod_mul (tmp = mypub1 * theirpub1 mod p)",
|
||||
__func__);
|
||||
if (BN_mod_mul(tmp, tmp, theirpub2, grp->p, bn_ctx) != 1)
|
||||
fatal("%s: BN_mod_mul (tmp = tmp * theirpub2 mod p)", __func__);
|
||||
|
||||
/*
|
||||
* client: a = tmp^exponent = g^((x1+x3+x4) * x2 * s) mod p
|
||||
* server: b = tmp^exponent = g^((x1+x2+x3) * x4 * s) mod p
|
||||
*/
|
||||
if (BN_mod_exp(*newpub, tmp, exponent, grp->p, bn_ctx) != 1)
|
||||
fatal("%s: BN_mod_mul (newpub = tmp^exponent mod p)", __func__);
|
||||
|
||||
JPAKE_DEBUG_BN((tmp, "%s: tmp = ", __func__));
|
||||
JPAKE_DEBUG_BN((exponent, "%s: exponent = ", __func__));
|
||||
|
||||
/* Note the generator here is 'tmp', not g */
|
||||
if (schnorr_sign_buf(grp->p, grp->q, tmp, exponent, *newpub,
|
||||
myid, myid_len,
|
||||
newpub_exponent_proof, newpub_exponent_proof_len) != 0)
|
||||
fatal("%s: schnorr_sign newpub", __func__);
|
||||
|
||||
BN_clear_free(tmp); /* XXX stash for later use? */
|
||||
BN_clear_free(exponent); /* XXX stash for later use? (yes, in conf) */
|
||||
|
||||
BN_CTX_free(bn_ctx);
|
||||
}
|
||||
|
||||
/* Confirmation hash calculation */
|
||||
void
|
||||
jpake_confirm_hash(const BIGNUM *k,
|
||||
const u_char *endpoint_id, u_int endpoint_id_len,
|
||||
const u_char *sess_id, u_int sess_id_len,
|
||||
u_char **confirm_hash, u_int *confirm_hash_len)
|
||||
{
|
||||
Buffer b;
|
||||
|
||||
/*
|
||||
* Calculate confirmation proof:
|
||||
* client: H(k || client_id || session_id)
|
||||
* server: H(k || server_id || session_id)
|
||||
*/
|
||||
buffer_init(&b);
|
||||
buffer_put_bignum2(&b, k);
|
||||
buffer_put_string(&b, endpoint_id, endpoint_id_len);
|
||||
buffer_put_string(&b, sess_id, sess_id_len);
|
||||
if (hash_buffer(buffer_ptr(&b), buffer_len(&b), EVP_sha256(),
|
||||
confirm_hash, confirm_hash_len) != 0)
|
||||
fatal("%s: hash_buffer", __func__);
|
||||
buffer_free(&b);
|
||||
}
|
||||
|
||||
/* Shared parts of key derivation and confirmation calculation */
|
||||
void
|
||||
jpake_key_confirm(struct modp_group *grp, BIGNUM *s, BIGNUM *step2_val,
|
||||
BIGNUM *mypriv2, BIGNUM *mypub1, BIGNUM *mypub2,
|
||||
BIGNUM *theirpub1, BIGNUM *theirpub2,
|
||||
const u_char *my_id, u_int my_id_len,
|
||||
const u_char *their_id, u_int their_id_len,
|
||||
const u_char *sess_id, u_int sess_id_len,
|
||||
const u_char *theirpriv2_s_proof, u_int theirpriv2_s_proof_len,
|
||||
BIGNUM **k,
|
||||
u_char **confirm_hash, u_int *confirm_hash_len)
|
||||
{
|
||||
BN_CTX *bn_ctx;
|
||||
BIGNUM *tmp;
|
||||
|
||||
if ((bn_ctx = BN_CTX_new()) == NULL)
|
||||
fatal("%s: BN_CTX_new", __func__);
|
||||
if ((tmp = BN_new()) == NULL ||
|
||||
(*k = BN_new()) == NULL)
|
||||
fatal("%s: BN_new", __func__);
|
||||
|
||||
/* Validate step 2 values */
|
||||
if (BN_cmp(step2_val, BN_value_one()) <= 0)
|
||||
fatal("%s: step2_val <= 1", __func__);
|
||||
if (BN_cmp(step2_val, grp->p) >= 0)
|
||||
fatal("%s: step2_val >= p", __func__);
|
||||
|
||||
/*
|
||||
* theirpriv2_s_proof is calculated with a different generator:
|
||||
* tmp = g^(mypriv1+mypriv2+theirpub1) = g^mypub1*g^mypub2*g^theirpub1
|
||||
* Calculate it here so we can check the signature.
|
||||
*/
|
||||
if (BN_mod_mul(tmp, mypub1, mypub2, grp->p, bn_ctx) != 1)
|
||||
fatal("%s: BN_mod_mul (tmp = mypub1 * mypub2 mod p)", __func__);
|
||||
if (BN_mod_mul(tmp, tmp, theirpub1, grp->p, bn_ctx) != 1)
|
||||
fatal("%s: BN_mod_mul (tmp = tmp * theirpub1 mod p)", __func__);
|
||||
|
||||
JPAKE_DEBUG_BN((tmp, "%s: tmp = ", __func__));
|
||||
|
||||
if (schnorr_verify_buf(grp->p, grp->q, tmp, step2_val,
|
||||
their_id, their_id_len,
|
||||
theirpriv2_s_proof, theirpriv2_s_proof_len) != 1)
|
||||
fatal("%s: schnorr_verify theirpriv2_s_proof failed", __func__);
|
||||
|
||||
/*
|
||||
* Derive shared key:
|
||||
* client: k = (b / g^(x2*x4*s))^x2 = g^((x1+x3)*x2*x4*s)
|
||||
* server: k = (a / g^(x2*x4*s))^x4 = g^((x1+x3)*x2*x4*s)
|
||||
*
|
||||
* Computed as:
|
||||
* client: k = (g_x4^(q - (x2 * s)) * b)^x2 mod p
|
||||
* server: k = (g_x2^(q - (x4 * s)) * b)^x4 mod p
|
||||
*/
|
||||
if (BN_mul(tmp, mypriv2, s, bn_ctx) != 1)
|
||||
fatal("%s: BN_mul (tmp = mypriv2 * s)", __func__);
|
||||
if (BN_mod_sub(tmp, grp->q, tmp, grp->q, bn_ctx) != 1)
|
||||
fatal("%s: BN_mod_sub (tmp = q - tmp mod q)", __func__);
|
||||
if (BN_mod_exp(tmp, theirpub2, tmp, grp->p, bn_ctx) != 1)
|
||||
fatal("%s: BN_mod_exp (tmp = theirpub2^tmp) mod p", __func__);
|
||||
if (BN_mod_mul(tmp, tmp, step2_val, grp->p, bn_ctx) != 1)
|
||||
fatal("%s: BN_mod_mul (tmp = tmp * step2_val) mod p", __func__);
|
||||
if (BN_mod_exp(*k, tmp, mypriv2, grp->p, bn_ctx) != 1)
|
||||
fatal("%s: BN_mod_exp (k = tmp^mypriv2) mod p", __func__);
|
||||
|
||||
BN_CTX_free(bn_ctx);
|
||||
BN_clear_free(tmp);
|
||||
|
||||
jpake_confirm_hash(*k, my_id, my_id_len, sess_id, sess_id_len,
|
||||
confirm_hash, confirm_hash_len);
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate and check confirmation hash from peer. Returns 1 on success
|
||||
* 0 on failure/mismatch.
|
||||
*/
|
||||
int
|
||||
jpake_check_confirm(const BIGNUM *k,
|
||||
const u_char *peer_id, u_int peer_id_len,
|
||||
const u_char *sess_id, u_int sess_id_len,
|
||||
const u_char *peer_confirm_hash, u_int peer_confirm_hash_len)
|
||||
{
|
||||
u_char *expected_confirm_hash;
|
||||
u_int expected_confirm_hash_len;
|
||||
int success = 0;
|
||||
|
||||
/* Calculate and verify expected confirmation hash */
|
||||
jpake_confirm_hash(k, peer_id, peer_id_len, sess_id, sess_id_len,
|
||||
&expected_confirm_hash, &expected_confirm_hash_len);
|
||||
|
||||
JPAKE_DEBUG_BUF((expected_confirm_hash, expected_confirm_hash_len,
|
||||
"%s: expected confirm hash", __func__));
|
||||
JPAKE_DEBUG_BUF((peer_confirm_hash, peer_confirm_hash_len,
|
||||
"%s: received confirm hash", __func__));
|
||||
|
||||
if (peer_confirm_hash_len != expected_confirm_hash_len)
|
||||
error("%s: confirmation length mismatch (my %u them %u)",
|
||||
__func__, expected_confirm_hash_len, peer_confirm_hash_len);
|
||||
else if (timingsafe_bcmp(peer_confirm_hash, expected_confirm_hash,
|
||||
expected_confirm_hash_len) == 0)
|
||||
success = 1;
|
||||
bzero(expected_confirm_hash, expected_confirm_hash_len);
|
||||
free(expected_confirm_hash);
|
||||
debug3("%s: success = %d", __func__, success);
|
||||
return success;
|
||||
}
|
||||
|
||||
/* XXX main() function with tests */
|
||||
|
||||
#endif /* JPAKE */
|
||||
|
114
jpake.h
114
jpake.h
@ -1,114 +0,0 @@
|
||||
/* $OpenBSD: jpake.h,v 1.2 2009/03/05 07:18:19 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.
|
||||
*/
|
||||
|
||||
#ifndef JPAKE_H
|
||||
#define JPAKE_H
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <openssl/bn.h>
|
||||
|
||||
/* Set JPAKE_DEBUG in CFLAGS for privacy-violating debugging */
|
||||
#ifndef JPAKE_DEBUG
|
||||
# define JPAKE_DEBUG_BN(a)
|
||||
# define JPAKE_DEBUG_BUF(a)
|
||||
# define JPAKE_DEBUG_CTX(a)
|
||||
#else
|
||||
# define JPAKE_DEBUG_BN(a) debug3_bn a
|
||||
# define JPAKE_DEBUG_BUF(a) debug3_buf a
|
||||
# define JPAKE_DEBUG_CTX(a) jpake_dump a
|
||||
#endif /* JPAKE_DEBUG */
|
||||
|
||||
#define KZP_ID_LEN 16 /* Length of client and server IDs */
|
||||
|
||||
struct jpake_ctx {
|
||||
/* Parameters */
|
||||
struct modp_group *grp;
|
||||
|
||||
/* Private values shared by client and server */
|
||||
BIGNUM *s; /* Secret (salted, crypted password) */
|
||||
BIGNUM *k; /* Derived key */
|
||||
|
||||
/* Client private values (NULL for server) */
|
||||
BIGNUM *x1; /* random in Zq */
|
||||
BIGNUM *x2; /* random in Z*q */
|
||||
|
||||
/* Server private values (NULL for server) */
|
||||
BIGNUM *x3; /* random in Zq */
|
||||
BIGNUM *x4; /* random in Z*q */
|
||||
|
||||
/* Step 1: C->S */
|
||||
u_char *client_id; /* Anti-replay nonce */
|
||||
u_int client_id_len;
|
||||
BIGNUM *g_x1; /* g^x1 */
|
||||
BIGNUM *g_x2; /* g^x2 */
|
||||
|
||||
/* Step 1: S->C */
|
||||
u_char *server_id; /* Anti-replay nonce */
|
||||
u_int server_id_len;
|
||||
BIGNUM *g_x3; /* g^x3 */
|
||||
BIGNUM *g_x4; /* g^x4 */
|
||||
|
||||
/* Step 2: C->S */
|
||||
BIGNUM *a; /* g^((x1+x3+x4)*x2*s) */
|
||||
|
||||
/* Step 2: S->C */
|
||||
BIGNUM *b; /* g^((x1+x2+x3)*x4*s) */
|
||||
|
||||
/* Confirmation: C->S */
|
||||
u_char *h_k_cid_sessid; /* H(k || client_id || session_id) */
|
||||
u_int h_k_cid_sessid_len;
|
||||
|
||||
/* Confirmation: S->C */
|
||||
u_char *h_k_sid_sessid; /* H(k || server_id || session_id) */
|
||||
u_int h_k_sid_sessid_len;
|
||||
};
|
||||
|
||||
/* jpake.c */
|
||||
struct modp_group *jpake_default_group(void);
|
||||
void jpake_dump(struct jpake_ctx *, const char *, ...)
|
||||
__attribute__((__nonnull__ (2)))
|
||||
__attribute__((format(printf, 2, 3)));
|
||||
struct jpake_ctx *jpake_new(void);
|
||||
void jpake_free(struct jpake_ctx *);
|
||||
|
||||
void jpake_step1(struct modp_group *, u_char **, u_int *,
|
||||
BIGNUM **, BIGNUM **, BIGNUM **, BIGNUM **,
|
||||
u_char **, u_int *, u_char **, u_int *);
|
||||
|
||||
void jpake_step2(struct modp_group *, BIGNUM *,
|
||||
BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *,
|
||||
const u_char *, u_int, const u_char *, u_int,
|
||||
const u_char *, u_int, const u_char *, u_int,
|
||||
BIGNUM **, u_char **, u_int *);
|
||||
|
||||
void jpake_confirm_hash(const BIGNUM *,
|
||||
const u_char *, u_int,
|
||||
const u_char *, u_int,
|
||||
u_char **, u_int *);
|
||||
|
||||
void jpake_key_confirm(struct modp_group *, BIGNUM *, BIGNUM *,
|
||||
BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *,
|
||||
const u_char *, u_int, const u_char *, u_int,
|
||||
const u_char *, u_int, const u_char *, u_int,
|
||||
BIGNUM **, u_char **, u_int *);
|
||||
|
||||
int jpake_check_confirm(const BIGNUM *, const u_char *, u_int,
|
||||
const u_char *, u_int, const u_char *, u_int);
|
||||
|
||||
#endif /* JPAKE_H */
|
||||
|
6
kex.c
6
kex.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: kex.c,v 1.97 2014/01/25 20:35:37 markus Exp $ */
|
||||
/* $OpenBSD: kex.c,v 1.98 2014/02/02 03:44:31 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
|
||||
*
|
||||
@ -666,8 +666,8 @@ derive_ssh1_session_id(BIGNUM *host_modulus, BIGNUM *server_modulus,
|
||||
fatal("%s: ssh_digest_final failed", __func__);
|
||||
memcpy(id, obuf, ssh_digest_bytes(SSH_DIGEST_MD5));
|
||||
|
||||
memset(nbuf, 0, sizeof(nbuf));
|
||||
memset(obuf, 0, sizeof(obuf));
|
||||
explicit_bzero(nbuf, sizeof(nbuf));
|
||||
explicit_bzero(obuf, sizeof(obuf));
|
||||
}
|
||||
|
||||
#if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH)
|
||||
|
7
kex.h
7
kex.h
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: kex.h,v 1.61 2014/01/25 10:12:50 dtucker Exp $ */
|
||||
/* $OpenBSD: kex.h,v 1.62 2014/01/27 18:58:14 markus Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
|
||||
@ -105,9 +105,8 @@ struct Mac {
|
||||
u_int key_len;
|
||||
int type;
|
||||
int etm; /* Encrypt-then-MAC */
|
||||
const EVP_MD *evp_md;
|
||||
HMAC_CTX evp_ctx;
|
||||
struct umac_ctx *umac_ctx;
|
||||
struct ssh_hmac_ctx *hmac_ctx;
|
||||
struct umac_ctx *umac_ctx;
|
||||
};
|
||||
struct Comp {
|
||||
int type;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: kexc25519.c,v 1.4 2014/01/12 08:13:13 djm Exp $ */
|
||||
/* $OpenBSD: kexc25519.c,v 1.5 2014/01/31 16:39:19 tedu Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2001, 2013 Markus Friedl. All rights reserved.
|
||||
* Copyright (c) 2010 Damien Miller. All rights reserved.
|
||||
@ -70,7 +70,7 @@ kexc25519_shared_key(const u_char key[CURVE25519_SIZE],
|
||||
#endif
|
||||
buffer_clear(out);
|
||||
buffer_put_bignum2_from_string(out, shared_key, CURVE25519_SIZE);
|
||||
memset(shared_key, 0, CURVE25519_SIZE); /* XXX explicit_bzero() */
|
||||
explicit_bzero(shared_key, CURVE25519_SIZE);
|
||||
}
|
||||
|
||||
void
|
||||
|
4
kexdhc.c
4
kexdhc.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: kexdhc.c,v 1.14 2014/01/12 08:13:13 djm Exp $ */
|
||||
/* $OpenBSD: kexdhc.c,v 1.15 2014/02/02 03:44:31 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2001 Markus Friedl. All rights reserved.
|
||||
*
|
||||
@ -124,7 +124,7 @@ kexdh_client(Kex *kex)
|
||||
fatal("kexdh_client: BN_new failed");
|
||||
if (BN_bin2bn(kbuf, kout, shared_secret) == NULL)
|
||||
fatal("kexdh_client: BN_bin2bn failed");
|
||||
memset(kbuf, 0, klen);
|
||||
explicit_bzero(kbuf, klen);
|
||||
free(kbuf);
|
||||
|
||||
/* calc and verify H */
|
||||
|
4
kexdhs.c
4
kexdhs.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: kexdhs.c,v 1.17 2014/01/12 08:13:13 djm Exp $ */
|
||||
/* $OpenBSD: kexdhs.c,v 1.18 2014/02/02 03:44:31 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2001 Markus Friedl. All rights reserved.
|
||||
*
|
||||
@ -110,7 +110,7 @@ kexdh_server(Kex *kex)
|
||||
fatal("kexdh_server: BN_new failed");
|
||||
if (BN_bin2bn(kbuf, kout, shared_secret) == NULL)
|
||||
fatal("kexdh_server: BN_bin2bn failed");
|
||||
memset(kbuf, 0, klen);
|
||||
explicit_bzero(kbuf, klen);
|
||||
free(kbuf);
|
||||
|
||||
key_to_blob(server_host_public, &server_host_key_blob, &sbloblen);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: kexecdhc.c,v 1.6 2014/01/12 08:13:13 djm Exp $ */
|
||||
/* $OpenBSD: kexecdhc.c,v 1.7 2014/02/02 03:44:31 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2001 Markus Friedl. All rights reserved.
|
||||
* Copyright (c) 2010 Damien Miller. All rights reserved.
|
||||
@ -119,7 +119,7 @@ kexecdh_client(Kex *kex)
|
||||
fatal("%s: BN_new failed", __func__);
|
||||
if (BN_bin2bn(kbuf, klen, shared_secret) == NULL)
|
||||
fatal("%s: BN_bin2bn failed", __func__);
|
||||
memset(kbuf, 0, klen);
|
||||
explicit_bzero(kbuf, klen);
|
||||
free(kbuf);
|
||||
|
||||
/* calc and verify H */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: kexecdhs.c,v 1.9 2014/01/12 08:13:13 djm Exp $ */
|
||||
/* $OpenBSD: kexecdhs.c,v 1.10 2014/02/02 03:44:31 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2001 Markus Friedl. All rights reserved.
|
||||
* Copyright (c) 2010 Damien Miller. All rights reserved.
|
||||
@ -103,7 +103,7 @@ kexecdh_server(Kex *kex)
|
||||
fatal("%s: BN_new failed", __func__);
|
||||
if (BN_bin2bn(kbuf, klen, shared_secret) == NULL)
|
||||
fatal("%s: BN_bin2bn failed", __func__);
|
||||
memset(kbuf, 0, klen);
|
||||
explicit_bzero(kbuf, klen);
|
||||
free(kbuf);
|
||||
|
||||
/* calc H */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: kexgexc.c,v 1.16 2014/01/25 10:12:50 dtucker Exp $ */
|
||||
/* $OpenBSD: kexgexc.c,v 1.17 2014/02/02 03:44:31 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000 Niels Provos. All rights reserved.
|
||||
* Copyright (c) 2001 Markus Friedl. All rights reserved.
|
||||
@ -162,7 +162,7 @@ kexgex_client(Kex *kex)
|
||||
fatal("kexgex_client: BN_new failed");
|
||||
if (BN_bin2bn(kbuf, kout, shared_secret) == NULL)
|
||||
fatal("kexgex_client: BN_bin2bn failed");
|
||||
memset(kbuf, 0, klen);
|
||||
explicit_bzero(kbuf, klen);
|
||||
free(kbuf);
|
||||
|
||||
if (datafellows & SSH_OLD_DHGEX)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: kexgexs.c,v 1.18 2014/01/12 08:13:13 djm Exp $ */
|
||||
/* $OpenBSD: kexgexs.c,v 1.19 2014/02/02 03:44:31 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000 Niels Provos. All rights reserved.
|
||||
* Copyright (c) 2001 Markus Friedl. All rights reserved.
|
||||
@ -150,7 +150,7 @@ kexgex_server(Kex *kex)
|
||||
fatal("kexgex_server: BN_new failed");
|
||||
if (BN_bin2bn(kbuf, kout, shared_secret) == NULL)
|
||||
fatal("kexgex_server: BN_bin2bn failed");
|
||||
memset(kbuf, 0, klen);
|
||||
explicit_bzero(kbuf, klen);
|
||||
free(kbuf);
|
||||
|
||||
key_to_blob(server_host_public, &server_host_key_blob, &sbloblen);
|
||||
|
12
key.c
12
key.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: key.c,v 1.115 2014/01/09 23:20:00 djm Exp $ */
|
||||
/* $OpenBSD: key.c,v 1.116 2014/02/02 03:44:31 djm Exp $ */
|
||||
/*
|
||||
* read_bignum():
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@ -242,12 +242,12 @@ key_free(Key *k)
|
||||
case KEY_ED25519:
|
||||
case KEY_ED25519_CERT:
|
||||
if (k->ed25519_pk) {
|
||||
memset(k->ed25519_pk, 0, ED25519_PK_SZ);
|
||||
explicit_bzero(k->ed25519_pk, ED25519_PK_SZ);
|
||||
free(k->ed25519_pk);
|
||||
k->ed25519_pk = NULL;
|
||||
}
|
||||
if (k->ed25519_sk) {
|
||||
memset(k->ed25519_sk, 0, ED25519_SK_SZ);
|
||||
explicit_bzero(k->ed25519_sk, ED25519_SK_SZ);
|
||||
free(k->ed25519_sk);
|
||||
k->ed25519_sk = NULL;
|
||||
}
|
||||
@ -415,7 +415,7 @@ key_fingerprint_raw(const Key *k, enum fp_type dgst_type,
|
||||
if ((ssh_digest_memory(hash_alg, blob, len,
|
||||
retval, SSH_DIGEST_MAX_LENGTH)) != 0)
|
||||
fatal("%s: digest_memory failed", __func__);
|
||||
memset(blob, 0, len);
|
||||
explicit_bzero(blob, len);
|
||||
free(blob);
|
||||
*dgst_raw_length = ssh_digest_bytes(hash_alg);
|
||||
} else {
|
||||
@ -623,7 +623,7 @@ key_fingerprint(const Key *k, enum fp_type dgst_type, enum fp_rep dgst_rep)
|
||||
dgst_rep);
|
||||
break;
|
||||
}
|
||||
memset(dgst_raw, 0, dgst_raw_len);
|
||||
explicit_bzero(dgst_raw, dgst_raw_len);
|
||||
free(dgst_raw);
|
||||
return retval;
|
||||
}
|
||||
@ -1744,7 +1744,7 @@ to_blob(const Key *key, u_char **blobp, u_int *lenp, int force_plain)
|
||||
*blobp = xmalloc(len);
|
||||
memcpy(*blobp, buffer_ptr(&b), len);
|
||||
}
|
||||
memset(buffer_ptr(&b), 0, len);
|
||||
explicit_bzero(buffer_ptr(&b), len);
|
||||
buffer_free(&b);
|
||||
return len;
|
||||
}
|
||||
|
12
krl.c
12
krl.c
@ -14,7 +14,7 @@
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $OpenBSD: krl.c,v 1.13 2013/07/20 22:20:42 djm Exp $ */
|
||||
/* $OpenBSD: krl.c,v 1.14 2014/01/31 16:39:19 tedu Exp $ */
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
@ -238,7 +238,7 @@ insert_serial_range(struct revoked_serial_tree *rt, u_int64_t lo, u_int64_t hi)
|
||||
struct revoked_serial rs, *ers, *crs, *irs;
|
||||
|
||||
KRL_DBG(("%s: insert %llu:%llu", __func__, lo, hi));
|
||||
bzero(&rs, sizeof(rs));
|
||||
memset(&rs, 0, sizeof(rs));
|
||||
rs.lo = lo;
|
||||
rs.hi = hi;
|
||||
ers = RB_NFIND(revoked_serial_tree, rt, &rs);
|
||||
@ -1115,7 +1115,7 @@ is_key_revoked(struct ssh_krl *krl, const Key *key)
|
||||
struct revoked_certs *rc;
|
||||
|
||||
/* Check explicitly revoked hashes first */
|
||||
bzero(&rb, sizeof(rb));
|
||||
memset(&rb, 0, sizeof(rb));
|
||||
if ((rb.blob = key_fingerprint_raw(key, SSH_FP_SHA1, &rb.len)) == NULL)
|
||||
return -1;
|
||||
erb = RB_FIND(revoked_blob_tree, &krl->revoked_sha1s, &rb);
|
||||
@ -1126,7 +1126,7 @@ is_key_revoked(struct ssh_krl *krl, const Key *key)
|
||||
}
|
||||
|
||||
/* Next, explicit keys */
|
||||
bzero(&rb, sizeof(rb));
|
||||
memset(&rb, 0, sizeof(rb));
|
||||
if (plain_key_blob(key, &rb.blob, &rb.len) != 0)
|
||||
return -1;
|
||||
erb = RB_FIND(revoked_blob_tree, &krl->revoked_keys, &rb);
|
||||
@ -1147,7 +1147,7 @@ is_key_revoked(struct ssh_krl *krl, const Key *key)
|
||||
return 0; /* No entry for this CA */
|
||||
|
||||
/* Check revocation by cert key ID */
|
||||
bzero(&rki, sizeof(rki));
|
||||
memset(&rki, 0, sizeof(rki));
|
||||
rki.key_id = key->cert->key_id;
|
||||
erki = RB_FIND(revoked_key_id_tree, &rc->revoked_key_ids, &rki);
|
||||
if (erki != NULL) {
|
||||
@ -1162,7 +1162,7 @@ is_key_revoked(struct ssh_krl *krl, const Key *key)
|
||||
if (key_cert_is_legacy(key) || key->cert->serial == 0)
|
||||
return 0;
|
||||
|
||||
bzero(&rs, sizeof(rs));
|
||||
memset(&rs, 0, sizeof(rs));
|
||||
rs.lo = rs.hi = key->cert->serial;
|
||||
ers = RB_FIND(revoked_serial_tree, &rc->revoked_serials, &rs);
|
||||
if (ers != NULL) {
|
||||
|
94
mac.c
94
mac.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: mac.c,v 1.26 2014/01/04 17:50:55 tedu Exp $ */
|
||||
/* $OpenBSD: mac.c,v 1.28 2014/02/07 06:55:54 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2001 Markus Friedl. All rights reserved.
|
||||
*
|
||||
@ -27,8 +27,6 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <openssl/hmac.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
@ -42,18 +40,20 @@
|
||||
#include "mac.h"
|
||||
#include "misc.h"
|
||||
|
||||
#include "digest.h"
|
||||
#include "hmac.h"
|
||||
#include "umac.h"
|
||||
|
||||
#include "openbsd-compat/openssl-compat.h"
|
||||
|
||||
#define SSH_EVP 1 /* OpenSSL EVP-based MAC */
|
||||
#define SSH_DIGEST 1 /* SSH_DIGEST_XXX */
|
||||
#define SSH_UMAC 2 /* UMAC (not integrated with OpenSSL) */
|
||||
#define SSH_UMAC128 3
|
||||
|
||||
struct macalg {
|
||||
char *name;
|
||||
int type;
|
||||
const EVP_MD * (*mdfunc)(void);
|
||||
int alg;
|
||||
int truncatebits; /* truncate digest if != 0 */
|
||||
int key_len; /* just for UMAC */
|
||||
int len; /* just for UMAC */
|
||||
@ -62,33 +62,33 @@ struct macalg {
|
||||
|
||||
static const struct macalg macs[] = {
|
||||
/* Encrypt-and-MAC (encrypt-and-authenticate) variants */
|
||||
{ "hmac-sha1", SSH_EVP, EVP_sha1, 0, 0, 0, 0 },
|
||||
{ "hmac-sha1-96", SSH_EVP, EVP_sha1, 96, 0, 0, 0 },
|
||||
{ "hmac-sha1", SSH_DIGEST, SSH_DIGEST_SHA1, 0, 0, 0, 0 },
|
||||
{ "hmac-sha1-96", SSH_DIGEST, SSH_DIGEST_SHA1, 96, 0, 0, 0 },
|
||||
#ifdef HAVE_EVP_SHA256
|
||||
{ "hmac-sha2-256", SSH_EVP, EVP_sha256, 0, 0, 0, 0 },
|
||||
{ "hmac-sha2-512", SSH_EVP, EVP_sha512, 0, 0, 0, 0 },
|
||||
{ "hmac-sha2-256", SSH_DIGEST, SSH_DIGEST_SHA256, 0, 0, 0, 0 },
|
||||
{ "hmac-sha2-512", SSH_DIGEST, SSH_DIGEST_SHA512, 0, 0, 0, 0 },
|
||||
#endif
|
||||
{ "hmac-md5", SSH_EVP, EVP_md5, 0, 0, 0, 0 },
|
||||
{ "hmac-md5-96", SSH_EVP, EVP_md5, 96, 0, 0, 0 },
|
||||
{ "hmac-ripemd160", SSH_EVP, EVP_ripemd160, 0, 0, 0, 0 },
|
||||
{ "hmac-ripemd160@openssh.com", SSH_EVP, EVP_ripemd160, 0, 0, 0, 0 },
|
||||
{ "umac-64@openssh.com", SSH_UMAC, NULL, 0, 128, 64, 0 },
|
||||
{ "umac-128@openssh.com", SSH_UMAC128, NULL, 0, 128, 128, 0 },
|
||||
{ "hmac-md5", SSH_DIGEST, SSH_DIGEST_MD5, 0, 0, 0, 0 },
|
||||
{ "hmac-md5-96", SSH_DIGEST, SSH_DIGEST_MD5, 96, 0, 0, 0 },
|
||||
{ "hmac-ripemd160", SSH_DIGEST, SSH_DIGEST_RIPEMD160, 0, 0, 0, 0 },
|
||||
{ "hmac-ripemd160@openssh.com", SSH_DIGEST, SSH_DIGEST_RIPEMD160, 0, 0, 0, 0 },
|
||||
{ "umac-64@openssh.com", SSH_UMAC, 0, 0, 128, 64, 0 },
|
||||
{ "umac-128@openssh.com", SSH_UMAC128, 0, 0, 128, 128, 0 },
|
||||
|
||||
/* Encrypt-then-MAC variants */
|
||||
{ "hmac-sha1-etm@openssh.com", SSH_EVP, EVP_sha1, 0, 0, 0, 1 },
|
||||
{ "hmac-sha1-96-etm@openssh.com", SSH_EVP, EVP_sha1, 96, 0, 0, 1 },
|
||||
{ "hmac-sha1-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_SHA1, 0, 0, 0, 1 },
|
||||
{ "hmac-sha1-96-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_SHA1, 96, 0, 0, 1 },
|
||||
#ifdef HAVE_EVP_SHA256
|
||||
{ "hmac-sha2-256-etm@openssh.com", SSH_EVP, EVP_sha256, 0, 0, 0, 1 },
|
||||
{ "hmac-sha2-512-etm@openssh.com", SSH_EVP, EVP_sha512, 0, 0, 0, 1 },
|
||||
{ "hmac-sha2-256-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_SHA256, 0, 0, 0, 1 },
|
||||
{ "hmac-sha2-512-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_SHA512, 0, 0, 0, 1 },
|
||||
#endif
|
||||
{ "hmac-md5-etm@openssh.com", SSH_EVP, EVP_md5, 0, 0, 0, 1 },
|
||||
{ "hmac-md5-96-etm@openssh.com", SSH_EVP, EVP_md5, 96, 0, 0, 1 },
|
||||
{ "hmac-ripemd160-etm@openssh.com", SSH_EVP, EVP_ripemd160, 0, 0, 0, 1 },
|
||||
{ "umac-64-etm@openssh.com", SSH_UMAC, NULL, 0, 128, 64, 1 },
|
||||
{ "umac-128-etm@openssh.com", SSH_UMAC128, NULL, 0, 128, 128, 1 },
|
||||
{ "hmac-md5-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_MD5, 0, 0, 0, 1 },
|
||||
{ "hmac-md5-96-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_MD5, 96, 0, 0, 1 },
|
||||
{ "hmac-ripemd160-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_RIPEMD160, 0, 0, 0, 1 },
|
||||
{ "umac-64-etm@openssh.com", SSH_UMAC, 0, 0, 128, 64, 1 },
|
||||
{ "umac-128-etm@openssh.com", SSH_UMAC128, 0, 0, 128, 128, 1 },
|
||||
|
||||
{ NULL, 0, NULL, 0, 0, 0, 0 }
|
||||
{ NULL, 0, 0, 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
/* Returns a list of supported MACs separated by the specified char. */
|
||||
@ -113,14 +113,11 @@ mac_alg_list(char sep)
|
||||
static void
|
||||
mac_setup_by_alg(Mac *mac, const struct macalg *macalg)
|
||||
{
|
||||
int evp_len;
|
||||
|
||||
mac->type = macalg->type;
|
||||
if (mac->type == SSH_EVP) {
|
||||
mac->evp_md = macalg->mdfunc();
|
||||
if ((evp_len = EVP_MD_size(mac->evp_md)) <= 0)
|
||||
fatal("mac %s len %d", mac->name, evp_len);
|
||||
mac->key_len = mac->mac_len = (u_int)evp_len;
|
||||
if (mac->type == SSH_DIGEST) {
|
||||
if ((mac->hmac_ctx = ssh_hmac_start(macalg->alg)) == NULL)
|
||||
fatal("ssh_hmac_start(alg=%d) failed", macalg->alg);
|
||||
mac->key_len = mac->mac_len = ssh_hmac_bytes(macalg->alg);
|
||||
} else {
|
||||
mac->mac_len = macalg->len / 8;
|
||||
mac->key_len = macalg->key_len / 8;
|
||||
@ -139,9 +136,10 @@ mac_setup(Mac *mac, char *name)
|
||||
for (m = macs; m->name != NULL; m++) {
|
||||
if (strcmp(name, m->name) != 0)
|
||||
continue;
|
||||
if (mac != NULL)
|
||||
if (mac != NULL) {
|
||||
mac_setup_by_alg(mac, m);
|
||||
debug2("mac_setup: found %s", name);
|
||||
debug2("mac_setup: setup %s", name);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
debug2("mac_setup: unknown %s", name);
|
||||
@ -152,13 +150,12 @@ int
|
||||
mac_init(Mac *mac)
|
||||
{
|
||||
if (mac->key == NULL)
|
||||
fatal("mac_init: no key");
|
||||
fatal("%s: no key", __func__);
|
||||
switch (mac->type) {
|
||||
case SSH_EVP:
|
||||
if (mac->evp_md == NULL)
|
||||
case SSH_DIGEST:
|
||||
if (mac->hmac_ctx == NULL ||
|
||||
ssh_hmac_init(mac->hmac_ctx, mac->key, mac->key_len) < 0)
|
||||
return -1;
|
||||
HMAC_CTX_init(&mac->evp_ctx);
|
||||
HMAC_Init(&mac->evp_ctx, mac->key, mac->key_len, mac->evp_md);
|
||||
return 0;
|
||||
case SSH_UMAC:
|
||||
mac->umac_ctx = umac_new(mac->key);
|
||||
@ -185,13 +182,14 @@ mac_compute(Mac *mac, u_int32_t seqno, u_char *data, int datalen)
|
||||
mac->mac_len, sizeof(u));
|
||||
|
||||
switch (mac->type) {
|
||||
case SSH_EVP:
|
||||
case SSH_DIGEST:
|
||||
put_u32(b, seqno);
|
||||
/* reset HMAC context */
|
||||
HMAC_Init(&mac->evp_ctx, NULL, 0, NULL);
|
||||
HMAC_Update(&mac->evp_ctx, b, sizeof(b));
|
||||
HMAC_Update(&mac->evp_ctx, data, datalen);
|
||||
HMAC_Final(&mac->evp_ctx, u.m, NULL);
|
||||
if (ssh_hmac_init(mac->hmac_ctx, NULL, 0) < 0 ||
|
||||
ssh_hmac_update(mac->hmac_ctx, b, sizeof(b)) < 0 ||
|
||||
ssh_hmac_update(mac->hmac_ctx, data, datalen) < 0 ||
|
||||
ssh_hmac_final(mac->hmac_ctx, u.m, sizeof(u.m)) < 0)
|
||||
fatal("ssh_hmac failed");
|
||||
break;
|
||||
case SSH_UMAC:
|
||||
put_u64(nonce, seqno);
|
||||
@ -218,9 +216,9 @@ mac_clear(Mac *mac)
|
||||
} else if (mac->type == SSH_UMAC128) {
|
||||
if (mac->umac_ctx != NULL)
|
||||
umac128_delete(mac->umac_ctx);
|
||||
} else if (mac->evp_md != NULL)
|
||||
HMAC_cleanup(&mac->evp_ctx);
|
||||
mac->evp_md = NULL;
|
||||
} else if (mac->hmac_ctx != NULL)
|
||||
ssh_hmac_free(mac->hmac_ctx);
|
||||
mac->hmac_ctx = NULL;
|
||||
mac->umac_ctx = NULL;
|
||||
}
|
||||
|
||||
@ -240,8 +238,6 @@ mac_valid(const char *names)
|
||||
debug("bad mac %s [%s]", p, names);
|
||||
free(maclist);
|
||||
return (0);
|
||||
} else {
|
||||
debug3("mac ok: %s [%s]", p, names);
|
||||
}
|
||||
}
|
||||
debug3("macs ok: [%s]", names);
|
||||
|
2
moduli.0
2
moduli.0
@ -71,4 +71,4 @@ STANDARDS
|
||||
the Secure Shell (SSH) Transport Layer Protocol, RFC 4419, March 2006,
|
||||
2006.
|
||||
|
||||
OpenBSD 5.4 September 26, 2012 OpenBSD 5.4
|
||||
OpenBSD 5.5 September 26, 2012 OpenBSD 5.5
|
||||
|
234
monitor.c
234
monitor.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: monitor.c,v 1.128 2013/11/04 11:51:16 markus Exp $ */
|
||||
/* $OpenBSD: monitor.c,v 1.131 2014/02/02 03:44:31 djm Exp $ */
|
||||
/*
|
||||
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
||||
* Copyright 2002 Markus Friedl <markus@openbsd.org>
|
||||
@ -95,7 +95,6 @@
|
||||
#include "misc.h"
|
||||
#include "compat.h"
|
||||
#include "ssh2.h"
|
||||
#include "jpake.h"
|
||||
#include "roaming.h"
|
||||
#include "authfd.h"
|
||||
|
||||
@ -161,11 +160,6 @@ int mm_answer_rsa_challenge(int, Buffer *);
|
||||
int mm_answer_rsa_response(int, Buffer *);
|
||||
int mm_answer_sesskey(int, Buffer *);
|
||||
int mm_answer_sessid(int, Buffer *);
|
||||
int mm_answer_jpake_get_pwdata(int, Buffer *);
|
||||
int mm_answer_jpake_step1(int, Buffer *);
|
||||
int mm_answer_jpake_step2(int, Buffer *);
|
||||
int mm_answer_jpake_key_confirm(int, Buffer *);
|
||||
int mm_answer_jpake_check_confirm(int, Buffer *);
|
||||
|
||||
#ifdef USE_PAM
|
||||
int mm_answer_pam_start(int, Buffer *);
|
||||
@ -253,13 +247,6 @@ struct mon_table mon_dispatch_proto20[] = {
|
||||
{MONITOR_REQ_GSSSTEP, MON_ISAUTH, mm_answer_gss_accept_ctx},
|
||||
{MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok},
|
||||
{MONITOR_REQ_GSSCHECKMIC, MON_ISAUTH, mm_answer_gss_checkmic},
|
||||
#endif
|
||||
#ifdef JPAKE
|
||||
{MONITOR_REQ_JPAKE_GET_PWDATA, MON_ONCE, mm_answer_jpake_get_pwdata},
|
||||
{MONITOR_REQ_JPAKE_STEP1, MON_ISAUTH, mm_answer_jpake_step1},
|
||||
{MONITOR_REQ_JPAKE_STEP2, MON_ONCE, mm_answer_jpake_step2},
|
||||
{MONITOR_REQ_JPAKE_KEY_CONFIRM, MON_ONCE, mm_answer_jpake_key_confirm},
|
||||
{MONITOR_REQ_JPAKE_CHECK_CONFIRM, MON_AUTH, mm_answer_jpake_check_confirm},
|
||||
#endif
|
||||
{0, 0, NULL}
|
||||
};
|
||||
@ -427,15 +414,6 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
|
||||
if (!authenticated)
|
||||
authctxt->failures++;
|
||||
}
|
||||
#ifdef JPAKE
|
||||
/* Cleanup JPAKE context after authentication */
|
||||
if (ent->flags & MON_AUTHDECIDE) {
|
||||
if (authctxt->jpake_ctx != NULL) {
|
||||
jpake_free(authctxt->jpake_ctx);
|
||||
authctxt->jpake_ctx = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!authctxt->valid)
|
||||
@ -566,7 +544,7 @@ monitor_read(struct monitor *pmonitor, struct mon_table *ent,
|
||||
struct pollfd pfd[2];
|
||||
|
||||
for (;;) {
|
||||
bzero(&pfd, sizeof(pfd));
|
||||
memset(&pfd, 0, sizeof(pfd));
|
||||
pfd[0].fd = pmonitor->m_sendfd;
|
||||
pfd[0].events = POLLIN;
|
||||
pfd[1].fd = pmonitor->m_log_recvfd;
|
||||
@ -880,7 +858,7 @@ mm_answer_authpassword(int sock, Buffer *m)
|
||||
/* Only authenticate if the context is valid */
|
||||
authenticated = options.password_authentication &&
|
||||
auth_password(authctxt, passwd);
|
||||
memset(passwd, 0, strlen(passwd));
|
||||
explicit_bzero(passwd, strlen(passwd));
|
||||
free(passwd);
|
||||
|
||||
buffer_clear(m);
|
||||
@ -1822,13 +1800,13 @@ monitor_apply_keystate(struct monitor *pmonitor)
|
||||
/* XXX inefficient for large buffers, need: buffer_init_from_string */
|
||||
buffer_clear(packet_get_input());
|
||||
buffer_append(packet_get_input(), child_state.input, child_state.ilen);
|
||||
memset(child_state.input, 0, child_state.ilen);
|
||||
explicit_bzero(child_state.input, child_state.ilen);
|
||||
free(child_state.input);
|
||||
|
||||
buffer_clear(packet_get_output());
|
||||
buffer_append(packet_get_output(), child_state.output,
|
||||
child_state.olen);
|
||||
memset(child_state.output, 0, child_state.olen);
|
||||
explicit_bzero(child_state.output, child_state.olen);
|
||||
free(child_state.output);
|
||||
|
||||
/* Roaming */
|
||||
@ -2159,205 +2137,3 @@ mm_answer_gss_userok(int sock, Buffer *m)
|
||||
}
|
||||
#endif /* GSSAPI */
|
||||
|
||||
#ifdef JPAKE
|
||||
int
|
||||
mm_answer_jpake_step1(int sock, Buffer *m)
|
||||
{
|
||||
struct jpake_ctx *pctx;
|
||||
u_char *x3_proof, *x4_proof;
|
||||
u_int x3_proof_len, x4_proof_len;
|
||||
|
||||
if (!options.zero_knowledge_password_authentication)
|
||||
fatal("zero_knowledge_password_authentication disabled");
|
||||
|
||||
if (authctxt->jpake_ctx != NULL)
|
||||
fatal("%s: authctxt->jpake_ctx already set (%p)",
|
||||
__func__, authctxt->jpake_ctx);
|
||||
authctxt->jpake_ctx = pctx = jpake_new();
|
||||
|
||||
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);
|
||||
|
||||
JPAKE_DEBUG_CTX((pctx, "step1 done in %s", __func__));
|
||||
|
||||
buffer_clear(m);
|
||||
|
||||
buffer_put_string(m, pctx->server_id, pctx->server_id_len);
|
||||
buffer_put_bignum2(m, pctx->g_x3);
|
||||
buffer_put_bignum2(m, pctx->g_x4);
|
||||
buffer_put_string(m, x3_proof, x3_proof_len);
|
||||
buffer_put_string(m, x4_proof, x4_proof_len);
|
||||
|
||||
debug3("%s: sending step1", __func__);
|
||||
mm_request_send(sock, MONITOR_ANS_JPAKE_STEP1, m);
|
||||
|
||||
bzero(x3_proof, x3_proof_len);
|
||||
bzero(x4_proof, x4_proof_len);
|
||||
free(x3_proof);
|
||||
free(x4_proof);
|
||||
|
||||
monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_GET_PWDATA, 1);
|
||||
monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_STEP1, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
mm_answer_jpake_get_pwdata(int sock, Buffer *m)
|
||||
{
|
||||
struct jpake_ctx *pctx = authctxt->jpake_ctx;
|
||||
char *hash_scheme, *salt;
|
||||
|
||||
if (pctx == NULL)
|
||||
fatal("%s: pctx == NULL", __func__);
|
||||
|
||||
auth2_jpake_get_pwdata(authctxt, &pctx->s, &hash_scheme, &salt);
|
||||
|
||||
buffer_clear(m);
|
||||
/* pctx->s is sensitive, not returned to slave */
|
||||
buffer_put_cstring(m, hash_scheme);
|
||||
buffer_put_cstring(m, salt);
|
||||
|
||||
debug3("%s: sending pwdata", __func__);
|
||||
mm_request_send(sock, MONITOR_ANS_JPAKE_GET_PWDATA, m);
|
||||
|
||||
bzero(hash_scheme, strlen(hash_scheme));
|
||||
bzero(salt, strlen(salt));
|
||||
free(hash_scheme);
|
||||
free(salt);
|
||||
|
||||
monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_STEP2, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
mm_answer_jpake_step2(int sock, Buffer *m)
|
||||
{
|
||||
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;
|
||||
|
||||
if (pctx == NULL)
|
||||
fatal("%s: pctx == NULL", __func__);
|
||||
|
||||
if ((pctx->g_x1 = BN_new()) == NULL ||
|
||||
(pctx->g_x2 = BN_new()) == NULL)
|
||||
fatal("%s: BN_new", __func__);
|
||||
buffer_get_bignum2(m, pctx->g_x1);
|
||||
buffer_get_bignum2(m, pctx->g_x2);
|
||||
pctx->client_id = buffer_get_string(m, &pctx->client_id_len);
|
||||
x1_proof = buffer_get_string(m, &x1_proof_len);
|
||||
x2_proof = buffer_get_string(m, &x2_proof_len);
|
||||
|
||||
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);
|
||||
|
||||
JPAKE_DEBUG_CTX((pctx, "step2 done in %s", __func__));
|
||||
|
||||
bzero(x1_proof, x1_proof_len);
|
||||
bzero(x2_proof, x2_proof_len);
|
||||
free(x1_proof);
|
||||
free(x2_proof);
|
||||
|
||||
buffer_clear(m);
|
||||
|
||||
buffer_put_bignum2(m, pctx->b);
|
||||
buffer_put_string(m, x4_s_proof, x4_s_proof_len);
|
||||
|
||||
debug3("%s: sending step2", __func__);
|
||||
mm_request_send(sock, MONITOR_ANS_JPAKE_STEP2, m);
|
||||
|
||||
bzero(x4_s_proof, x4_s_proof_len);
|
||||
free(x4_s_proof);
|
||||
|
||||
monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_KEY_CONFIRM, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
mm_answer_jpake_key_confirm(int sock, Buffer *m)
|
||||
{
|
||||
struct jpake_ctx *pctx = authctxt->jpake_ctx;
|
||||
u_char *x2_s_proof;
|
||||
u_int x2_s_proof_len;
|
||||
|
||||
if (pctx == NULL)
|
||||
fatal("%s: pctx == NULL", __func__);
|
||||
|
||||
if ((pctx->a = BN_new()) == NULL)
|
||||
fatal("%s: BN_new", __func__);
|
||||
buffer_get_bignum2(m, pctx->a);
|
||||
x2_s_proof = buffer_get_string(m, &x2_s_proof_len);
|
||||
|
||||
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);
|
||||
|
||||
JPAKE_DEBUG_CTX((pctx, "key_confirm done in %s", __func__));
|
||||
|
||||
bzero(x2_s_proof, x2_s_proof_len);
|
||||
buffer_clear(m);
|
||||
|
||||
/* pctx->k is sensitive, not sent */
|
||||
buffer_put_string(m, pctx->h_k_sid_sessid, pctx->h_k_sid_sessid_len);
|
||||
|
||||
debug3("%s: sending confirmation hash", __func__);
|
||||
mm_request_send(sock, MONITOR_ANS_JPAKE_KEY_CONFIRM, m);
|
||||
|
||||
monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_CHECK_CONFIRM, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
mm_answer_jpake_check_confirm(int sock, Buffer *m)
|
||||
{
|
||||
int authenticated = 0;
|
||||
u_char *peer_confirm_hash;
|
||||
u_int peer_confirm_hash_len;
|
||||
struct jpake_ctx *pctx = authctxt->jpake_ctx;
|
||||
|
||||
if (pctx == NULL)
|
||||
fatal("%s: pctx == NULL", __func__);
|
||||
|
||||
peer_confirm_hash = buffer_get_string(m, &peer_confirm_hash_len);
|
||||
|
||||
authenticated = jpake_check_confirm(pctx->k,
|
||||
pctx->client_id, pctx->client_id_len,
|
||||
session_id2, session_id2_len,
|
||||
peer_confirm_hash, peer_confirm_hash_len) && authctxt->valid;
|
||||
|
||||
JPAKE_DEBUG_CTX((pctx, "check_confirm done in %s", __func__));
|
||||
|
||||
bzero(peer_confirm_hash, peer_confirm_hash_len);
|
||||
free(peer_confirm_hash);
|
||||
|
||||
buffer_clear(m);
|
||||
buffer_put_int(m, authenticated);
|
||||
|
||||
debug3("%s: sending result %d", __func__, authenticated);
|
||||
mm_request_send(sock, MONITOR_ANS_JPAKE_CHECK_CONFIRM, m);
|
||||
|
||||
monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_STEP1, 1);
|
||||
|
||||
auth_method = "jpake-01@openssh.com";
|
||||
return authenticated;
|
||||
}
|
||||
|
||||
#endif /* JPAKE */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: monitor.h,v 1.17 2012/12/02 20:34:10 djm Exp $ */
|
||||
/* $OpenBSD: monitor.h,v 1.18 2014/01/29 06:18:35 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
||||
@ -56,11 +56,6 @@ enum monitor_reqtype {
|
||||
MONITOR_REQ_GSSUSEROK = 46, MONITOR_ANS_GSSUSEROK = 47,
|
||||
MONITOR_REQ_GSSCHECKMIC = 48, MONITOR_ANS_GSSCHECKMIC = 49,
|
||||
MONITOR_REQ_TERM = 50,
|
||||
MONITOR_REQ_JPAKE_STEP1 = 52, MONITOR_ANS_JPAKE_STEP1 = 53,
|
||||
MONITOR_REQ_JPAKE_GET_PWDATA = 54, MONITOR_ANS_JPAKE_GET_PWDATA = 55,
|
||||
MONITOR_REQ_JPAKE_STEP2 = 56, MONITOR_ANS_JPAKE_STEP2 = 57,
|
||||
MONITOR_REQ_JPAKE_KEY_CONFIRM = 58, MONITOR_ANS_JPAKE_KEY_CONFIRM = 59,
|
||||
MONITOR_REQ_JPAKE_CHECK_CONFIRM = 60, MONITOR_ANS_JPAKE_CHECK_CONFIRM = 61,
|
||||
|
||||
MONITOR_REQ_PAM_START = 100,
|
||||
MONITOR_REQ_PAM_ACCOUNT = 102, MONITOR_ANS_PAM_ACCOUNT = 103,
|
||||
|
169
monitor_wrap.c
169
monitor_wrap.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: monitor_wrap.c,v 1.77 2013/11/06 16:52:11 markus Exp $ */
|
||||
/* $OpenBSD: monitor_wrap.c,v 1.79 2014/02/02 03:44:31 djm Exp $ */
|
||||
/*
|
||||
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
||||
* Copyright 2002 Markus Friedl <markus@openbsd.org>
|
||||
@ -71,8 +71,6 @@
|
||||
#include "atomicio.h"
|
||||
#include "monitor_fdpass.h"
|
||||
#include "misc.h"
|
||||
#include "schnorr.h"
|
||||
#include "jpake.h"
|
||||
#include "uuencode.h"
|
||||
|
||||
#include "channels.h"
|
||||
@ -574,7 +572,7 @@ mm_newkeys_to_blob(int mode, u_char **blobp, u_int *lenp)
|
||||
*blobp = xmalloc(len);
|
||||
memcpy(*blobp, buffer_ptr(&b), len);
|
||||
}
|
||||
memset(buffer_ptr(&b), 0, len);
|
||||
explicit_bzero(buffer_ptr(&b), len);
|
||||
buffer_free(&b);
|
||||
return len;
|
||||
}
|
||||
@ -618,7 +616,7 @@ mm_send_keystate(struct monitor *monitor)
|
||||
key = xmalloc(keylen+1); /* add 1 if keylen == 0 */
|
||||
keylen = packet_get_encryption_key(key);
|
||||
buffer_put_string(&m, key, keylen);
|
||||
memset(key, 0, keylen);
|
||||
explicit_bzero(key, keylen);
|
||||
free(key);
|
||||
|
||||
ivlen = packet_get_keyiv_len(MODE_OUT);
|
||||
@ -1292,164 +1290,3 @@ mm_ssh_gssapi_userok(char *user)
|
||||
}
|
||||
#endif /* GSSAPI */
|
||||
|
||||
#ifdef JPAKE
|
||||
void
|
||||
mm_auth2_jpake_get_pwdata(Authctxt *authctxt, BIGNUM **s,
|
||||
char **hash_scheme, char **salt)
|
||||
{
|
||||
Buffer m;
|
||||
|
||||
debug3("%s entering", __func__);
|
||||
|
||||
buffer_init(&m);
|
||||
mm_request_send(pmonitor->m_recvfd,
|
||||
MONITOR_REQ_JPAKE_GET_PWDATA, &m);
|
||||
|
||||
debug3("%s: waiting for MONITOR_ANS_JPAKE_GET_PWDATA", __func__);
|
||||
mm_request_receive_expect(pmonitor->m_recvfd,
|
||||
MONITOR_ANS_JPAKE_GET_PWDATA, &m);
|
||||
|
||||
*hash_scheme = buffer_get_string(&m, NULL);
|
||||
*salt = buffer_get_string(&m, NULL);
|
||||
|
||||
buffer_free(&m);
|
||||
}
|
||||
|
||||
void
|
||||
mm_jpake_step1(struct modp_group *grp,
|
||||
u_char **id, u_int *id_len,
|
||||
BIGNUM **priv1, BIGNUM **priv2, BIGNUM **g_priv1, BIGNUM **g_priv2,
|
||||
u_char **priv1_proof, u_int *priv1_proof_len,
|
||||
u_char **priv2_proof, u_int *priv2_proof_len)
|
||||
{
|
||||
Buffer m;
|
||||
|
||||
debug3("%s entering", __func__);
|
||||
|
||||
buffer_init(&m);
|
||||
mm_request_send(pmonitor->m_recvfd,
|
||||
MONITOR_REQ_JPAKE_STEP1, &m);
|
||||
|
||||
debug3("%s: waiting for MONITOR_ANS_JPAKE_STEP1", __func__);
|
||||
mm_request_receive_expect(pmonitor->m_recvfd,
|
||||
MONITOR_ANS_JPAKE_STEP1, &m);
|
||||
|
||||
if ((*priv1 = BN_new()) == NULL ||
|
||||
(*priv2 = BN_new()) == NULL ||
|
||||
(*g_priv1 = BN_new()) == NULL ||
|
||||
(*g_priv2 = BN_new()) == NULL)
|
||||
fatal("%s: BN_new", __func__);
|
||||
|
||||
*id = buffer_get_string(&m, id_len);
|
||||
/* priv1 and priv2 are, well, private */
|
||||
buffer_get_bignum2(&m, *g_priv1);
|
||||
buffer_get_bignum2(&m, *g_priv2);
|
||||
*priv1_proof = buffer_get_string(&m, priv1_proof_len);
|
||||
*priv2_proof = buffer_get_string(&m, priv2_proof_len);
|
||||
|
||||
buffer_free(&m);
|
||||
}
|
||||
|
||||
void
|
||||
mm_jpake_step2(struct modp_group *grp, BIGNUM *s,
|
||||
BIGNUM *mypub1, BIGNUM *theirpub1, BIGNUM *theirpub2, BIGNUM *mypriv2,
|
||||
const u_char *theirid, u_int theirid_len,
|
||||
const u_char *myid, u_int myid_len,
|
||||
const u_char *theirpub1_proof, u_int theirpub1_proof_len,
|
||||
const u_char *theirpub2_proof, u_int theirpub2_proof_len,
|
||||
BIGNUM **newpub,
|
||||
u_char **newpub_exponent_proof, u_int *newpub_exponent_proof_len)
|
||||
{
|
||||
Buffer m;
|
||||
|
||||
debug3("%s entering", __func__);
|
||||
|
||||
buffer_init(&m);
|
||||
/* monitor already has all bignums except theirpub1, theirpub2 */
|
||||
buffer_put_bignum2(&m, theirpub1);
|
||||
buffer_put_bignum2(&m, theirpub2);
|
||||
/* monitor already knows our id */
|
||||
buffer_put_string(&m, theirid, theirid_len);
|
||||
buffer_put_string(&m, theirpub1_proof, theirpub1_proof_len);
|
||||
buffer_put_string(&m, theirpub2_proof, theirpub2_proof_len);
|
||||
|
||||
mm_request_send(pmonitor->m_recvfd,
|
||||
MONITOR_REQ_JPAKE_STEP2, &m);
|
||||
|
||||
debug3("%s: waiting for MONITOR_ANS_JPAKE_STEP2", __func__);
|
||||
mm_request_receive_expect(pmonitor->m_recvfd,
|
||||
MONITOR_ANS_JPAKE_STEP2, &m);
|
||||
|
||||
if ((*newpub = BN_new()) == NULL)
|
||||
fatal("%s: BN_new", __func__);
|
||||
|
||||
buffer_get_bignum2(&m, *newpub);
|
||||
*newpub_exponent_proof = buffer_get_string(&m,
|
||||
newpub_exponent_proof_len);
|
||||
|
||||
buffer_free(&m);
|
||||
}
|
||||
|
||||
void
|
||||
mm_jpake_key_confirm(struct modp_group *grp, BIGNUM *s, BIGNUM *step2_val,
|
||||
BIGNUM *mypriv2, BIGNUM *mypub1, BIGNUM *mypub2,
|
||||
BIGNUM *theirpub1, BIGNUM *theirpub2,
|
||||
const u_char *my_id, u_int my_id_len,
|
||||
const u_char *their_id, u_int their_id_len,
|
||||
const u_char *sess_id, u_int sess_id_len,
|
||||
const u_char *theirpriv2_s_proof, u_int theirpriv2_s_proof_len,
|
||||
BIGNUM **k,
|
||||
u_char **confirm_hash, u_int *confirm_hash_len)
|
||||
{
|
||||
Buffer m;
|
||||
|
||||
debug3("%s entering", __func__);
|
||||
|
||||
buffer_init(&m);
|
||||
/* monitor already has all bignums except step2_val */
|
||||
buffer_put_bignum2(&m, step2_val);
|
||||
/* monitor already knows all the ids */
|
||||
buffer_put_string(&m, theirpriv2_s_proof, theirpriv2_s_proof_len);
|
||||
|
||||
mm_request_send(pmonitor->m_recvfd,
|
||||
MONITOR_REQ_JPAKE_KEY_CONFIRM, &m);
|
||||
|
||||
debug3("%s: waiting for MONITOR_ANS_JPAKE_KEY_CONFIRM", __func__);
|
||||
mm_request_receive_expect(pmonitor->m_recvfd,
|
||||
MONITOR_ANS_JPAKE_KEY_CONFIRM, &m);
|
||||
|
||||
/* 'k' is sensitive and stays in the monitor */
|
||||
*confirm_hash = buffer_get_string(&m, confirm_hash_len);
|
||||
|
||||
buffer_free(&m);
|
||||
}
|
||||
|
||||
int
|
||||
mm_jpake_check_confirm(const BIGNUM *k,
|
||||
const u_char *peer_id, u_int peer_id_len,
|
||||
const u_char *sess_id, u_int sess_id_len,
|
||||
const u_char *peer_confirm_hash, u_int peer_confirm_hash_len)
|
||||
{
|
||||
Buffer m;
|
||||
int success = 0;
|
||||
|
||||
debug3("%s entering", __func__);
|
||||
|
||||
buffer_init(&m);
|
||||
/* k is dummy in slave, ignored */
|
||||
/* monitor knows all the ids */
|
||||
buffer_put_string(&m, peer_confirm_hash, peer_confirm_hash_len);
|
||||
mm_request_send(pmonitor->m_recvfd,
|
||||
MONITOR_REQ_JPAKE_CHECK_CONFIRM, &m);
|
||||
|
||||
debug3("%s: waiting for MONITOR_ANS_JPAKE_CHECK_CONFIRM", __func__);
|
||||
mm_request_receive_expect(pmonitor->m_recvfd,
|
||||
MONITOR_ANS_JPAKE_CHECK_CONFIRM, &m);
|
||||
|
||||
success = buffer_get_int(&m);
|
||||
buffer_free(&m);
|
||||
|
||||
debug3("%s: success = %d", __func__, success);
|
||||
return success;
|
||||
}
|
||||
#endif /* JPAKE */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: monitor_wrap.h,v 1.23 2011/06/17 21:44:31 djm Exp $ */
|
||||
/* $OpenBSD: monitor_wrap.h,v 1.24 2014/01/29 06:18:35 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
||||
@ -102,26 +102,6 @@ int mm_bsdauth_respond(void *, u_int, char **);
|
||||
int mm_skey_query(void *, char **, char **, u_int *, char ***, u_int **);
|
||||
int mm_skey_respond(void *, u_int, char **);
|
||||
|
||||
/* jpake */
|
||||
struct modp_group;
|
||||
void mm_auth2_jpake_get_pwdata(struct Authctxt *, BIGNUM **, char **, char **);
|
||||
void mm_jpake_step1(struct modp_group *, u_char **, u_int *,
|
||||
BIGNUM **, BIGNUM **, BIGNUM **, BIGNUM **,
|
||||
u_char **, u_int *, u_char **, u_int *);
|
||||
void mm_jpake_step2(struct modp_group *, BIGNUM *,
|
||||
BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *,
|
||||
const u_char *, u_int, const u_char *, u_int,
|
||||
const u_char *, u_int, const u_char *, u_int,
|
||||
BIGNUM **, u_char **, u_int *);
|
||||
void mm_jpake_key_confirm(struct modp_group *, BIGNUM *, BIGNUM *,
|
||||
BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *,
|
||||
const u_char *, u_int, const u_char *, u_int,
|
||||
const u_char *, u_int, const u_char *, u_int,
|
||||
BIGNUM **, u_char **, u_int *);
|
||||
int mm_jpake_check_confirm(const BIGNUM *,
|
||||
const u_char *, u_int, const u_char *, u_int, const u_char *, u_int);
|
||||
|
||||
|
||||
/* zlib allocation hooks */
|
||||
|
||||
void *mm_zalloc(struct mm_master *, u_int, u_int);
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $Id: Makefile.in,v 1.54 2013/12/07 01:37:54 djm Exp $
|
||||
# $Id: Makefile.in,v 1.55 2014/02/04 00:37:50 djm Exp $
|
||||
|
||||
sysconfdir=@sysconfdir@
|
||||
piddir=@piddir@
|
||||
@ -16,7 +16,7 @@ RANLIB=@RANLIB@
|
||||
INSTALL=@INSTALL@
|
||||
LDFLAGS=-L. @LDFLAGS@
|
||||
|
||||
OPENBSD=base64.o basename.o bcrypt_pbkdf.o bindresvport.o blowfish.o daemon.o dirname.o fmt_scaled.o getcwd.o getgrouplist.o getopt_long.o getrrsetbyname.o glob.o inet_aton.o inet_ntoa.o inet_ntop.o mktemp.o pwcache.o readpassphrase.o realpath.o rresvport.o setenv.o setproctitle.o sha2.o sigact.o strlcat.o strlcpy.o strmode.o strnlen.o strptime.o strsep.o strtonum.o strtoll.o strtoul.o strtoull.o timingsafe_bcmp.o vis.o blowfish.o bcrypt_pbkdf.o
|
||||
OPENBSD=base64.o basename.o bcrypt_pbkdf.o bindresvport.o blowfish.o daemon.o dirname.o fmt_scaled.o getcwd.o getgrouplist.o getopt_long.o getrrsetbyname.o glob.o inet_aton.o inet_ntoa.o inet_ntop.o mktemp.o pwcache.o readpassphrase.o realpath.o rresvport.o setenv.o setproctitle.o sha2.o sigact.o strlcat.o strlcpy.o strmode.o strnlen.o strptime.o strsep.o strtonum.o strtoll.o strtoul.o strtoull.o timingsafe_bcmp.o vis.o blowfish.o bcrypt_pbkdf.o explicit_bzero.o
|
||||
|
||||
COMPAT=arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-setres_id.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xmmap.o xcrypt.o
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: bsd-poll.c,v 1.5 2013/11/08 10:12:58 dtucker Exp $ */
|
||||
/* $Id: bsd-poll.c,v 1.6 2014/02/05 23:44:13 dtucker Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004, 2005, 2007 Darren Tucker (dtucker at zip com au).
|
||||
@ -109,12 +109,9 @@ poll(struct pollfd *fds, nfds_t nfds, int timeout)
|
||||
}
|
||||
|
||||
out:
|
||||
if (readfds != NULL)
|
||||
free(readfds);
|
||||
if (writefds != NULL)
|
||||
free(writefds);
|
||||
if (exceptfds != NULL)
|
||||
free(exceptfds);
|
||||
free(readfds);
|
||||
free(writefds);
|
||||
free(exceptfds);
|
||||
if (ret == -1)
|
||||
errno = saved_errno;
|
||||
return ret;
|
||||
|
20
openbsd-compat/explicit_bzero.c
Normal file
20
openbsd-compat/explicit_bzero.c
Normal file
@ -0,0 +1,20 @@
|
||||
/* OPENBSD ORIGINAL: lib/libc/string/explicit_bzero.c */
|
||||
/* $OpenBSD: explicit_bzero.c,v 1.1 2014/01/22 21:06:45 tedu Exp $ */
|
||||
/*
|
||||
* Public domain.
|
||||
* Written by Ted Unangst
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#ifndef HAVE_EXPLICIT_BZERO
|
||||
|
||||
/*
|
||||
* explicit_bzero - don't let the compiler optimize away bzero
|
||||
*/
|
||||
void
|
||||
explicit_bzero(void *p, size_t n)
|
||||
{
|
||||
bzero(p, n);
|
||||
}
|
||||
#endif
|
@ -1,4 +1,4 @@
|
||||
/* $Id: openbsd-compat.h,v 1.60 2013/12/07 00:51:54 djm Exp $ */
|
||||
/* $Id: openbsd-compat.h,v 1.61 2014/02/04 00:18:23 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1999-2003 Damien Miller. All rights reserved.
|
||||
@ -246,6 +246,10 @@ int bcrypt_pbkdf(const char *, size_t, const u_int8_t *, size_t,
|
||||
u_int8_t *, size_t, unsigned int);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_EXPLICIT_BZERO
|
||||
void explicit_bzero(void *p, size_t n);
|
||||
#endif
|
||||
|
||||
void *xmmap(size_t size);
|
||||
char *xcrypt(const char *password, const char *salt);
|
||||
char *shadow_pw(struct passwd *pw);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: openssl-compat.c,v 1.16 2014/01/17 07:00:41 dtucker Exp $ */
|
||||
/* $Id: openssl-compat.c,v 1.17 2014/02/13 05:38:33 dtucker Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2005 Darren Tucker <dtucker@zip.com.au>
|
||||
@ -96,6 +96,14 @@ ssh_EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *d, unsigned int cnt)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_EVP_MD_CTX_COPY_EX
|
||||
int
|
||||
EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in)
|
||||
{
|
||||
return EVP_MD_CTX_copy(out, in);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_BN_IS_PRIME_EX
|
||||
int
|
||||
BN_is_prime_ex(const BIGNUM *p, int nchecks, BN_CTX *ctx, void *cb)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: openssl-compat.h,v 1.25 2014/01/17 06:32:31 dtucker Exp $ */
|
||||
/* $Id: openssl-compat.h,v 1.26 2014/02/13 05:38:33 dtucker Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2005 Darren Tucker <dtucker@zip.com.au>
|
||||
@ -156,6 +156,10 @@ int EVP_DigestInit_ex(EVP_MD_CTX *, const EVP_MD *, void *);
|
||||
int EVP_DigestFinal_ex(EVP_MD_CTX *, unsigned char *, unsigned int *);
|
||||
# endif
|
||||
|
||||
# ifndef EVP_MD_CTX_COPY_EX
|
||||
int EVP_MD_CTX_copy_ex(EVP_MD_CTX *, const EVP_MD_CTX *);
|
||||
# endif
|
||||
|
||||
int ssh_EVP_CipherInit(EVP_CIPHER_CTX *, const EVP_CIPHER *, unsigned char *,
|
||||
unsigned char *, int);
|
||||
int ssh_EVP_Cipher(EVP_CIPHER_CTX *, char *, char *, int);
|
||||
|
16
packet.c
16
packet.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: packet.c,v 1.191 2013/12/06 13:34:54 markus Exp $ */
|
||||
/* $OpenBSD: packet.c,v 1.192 2014/02/02 03:44:31 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@ -764,9 +764,9 @@ set_newkeys(int mode)
|
||||
mac = &active_state->newkeys[mode]->mac;
|
||||
comp = &active_state->newkeys[mode]->comp;
|
||||
mac_clear(mac);
|
||||
memset(enc->iv, 0, enc->iv_len);
|
||||
memset(enc->key, 0, enc->key_len);
|
||||
memset(mac->key, 0, mac->key_len);
|
||||
explicit_bzero(enc->iv, enc->iv_len);
|
||||
explicit_bzero(enc->key, enc->key_len);
|
||||
explicit_bzero(mac->key, mac->key_len);
|
||||
free(enc->name);
|
||||
free(enc->iv);
|
||||
free(enc->key);
|
||||
@ -787,9 +787,9 @@ set_newkeys(int mode)
|
||||
cipher_init(cc, enc->cipher, enc->key, enc->key_len,
|
||||
enc->iv, enc->iv_len, crypt_type);
|
||||
/* Deleting the keys does not gain extra security */
|
||||
/* memset(enc->iv, 0, enc->block_size);
|
||||
memset(enc->key, 0, enc->key_len);
|
||||
memset(mac->key, 0, mac->key_len); */
|
||||
/* explicit_bzero(enc->iv, enc->block_size);
|
||||
explicit_bzero(enc->key, enc->key_len);
|
||||
explicit_bzero(mac->key, mac->key_len); */
|
||||
if ((comp->type == COMP_ZLIB ||
|
||||
(comp->type == COMP_DELAYED &&
|
||||
active_state->after_authentication)) && comp->enabled == 0) {
|
||||
@ -928,7 +928,7 @@ packet_send2_wrapped(void)
|
||||
}
|
||||
} else {
|
||||
/* clear padding */
|
||||
memset(cp, 0, padlen);
|
||||
explicit_bzero(cp, padlen);
|
||||
}
|
||||
/* sizeof (packet_len + pad_len + payload + padding) */
|
||||
len = buffer_len(&active_state->outgoing_packet);
|
||||
|
72
readconf.c
72
readconf.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: readconf.c,v 1.215 2013/12/06 13:39:49 markus Exp $ */
|
||||
/* $OpenBSD: readconf.c,v 1.218 2014/02/23 20:11:36 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@ -22,6 +22,7 @@
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
@ -144,7 +145,7 @@ typedef enum {
|
||||
oSendEnv, oControlPath, oControlMaster, oControlPersist,
|
||||
oHashKnownHosts,
|
||||
oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
|
||||
oVisualHostKey, oUseRoaming, oZeroKnowledgePasswordAuthentication,
|
||||
oVisualHostKey, oUseRoaming,
|
||||
oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass,
|
||||
oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots,
|
||||
oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs,
|
||||
@ -251,12 +252,6 @@ static struct {
|
||||
{ "permitlocalcommand", oPermitLocalCommand },
|
||||
{ "visualhostkey", oVisualHostKey },
|
||||
{ "useroaming", oUseRoaming },
|
||||
#ifdef JPAKE
|
||||
{ "zeroknowledgepasswordauthentication",
|
||||
oZeroKnowledgePasswordAuthentication },
|
||||
#else
|
||||
{ "zeroknowledgepasswordauthentication", oUnsupported },
|
||||
#endif
|
||||
{ "kexalgorithms", oKexAlgorithms },
|
||||
{ "ipqos", oIPQoS },
|
||||
{ "requesttty", oRequestTTY },
|
||||
@ -542,16 +537,27 @@ match_cfg_line(Options *options, char **condition, struct passwd *pw,
|
||||
"r", ruser,
|
||||
"u", pw->pw_name,
|
||||
(char *)NULL);
|
||||
r = execute_in_shell(cmd);
|
||||
if (r == -1) {
|
||||
fatal("%.200s line %d: match exec '%.100s' "
|
||||
"error", filename, linenum, cmd);
|
||||
} else if (r == 0) {
|
||||
debug("%.200s line %d: matched "
|
||||
"'exec \"%.100s\"' ",
|
||||
if (result != 1) {
|
||||
/* skip execution if prior predicate failed */
|
||||
debug("%.200s line %d: skipped exec \"%.100s\"",
|
||||
filename, linenum, cmd);
|
||||
} else
|
||||
result = 0;
|
||||
} else {
|
||||
r = execute_in_shell(cmd);
|
||||
if (r == -1) {
|
||||
fatal("%.200s line %d: match exec "
|
||||
"'%.100s' error", filename,
|
||||
linenum, cmd);
|
||||
} else if (r == 0) {
|
||||
debug("%.200s line %d: matched "
|
||||
"'exec \"%.100s\"'", filename,
|
||||
linenum, cmd);
|
||||
} else {
|
||||
debug("%.200s line %d: no match "
|
||||
"'exec \"%.100s\"'", filename,
|
||||
linenum, cmd);
|
||||
result = 0;
|
||||
}
|
||||
}
|
||||
free(cmd);
|
||||
} else {
|
||||
error("Unsupported Match attribute %s", attrib);
|
||||
@ -803,10 +809,6 @@ process_config_line(Options *options, struct passwd *pw, const char *host,
|
||||
intptr = &options->password_authentication;
|
||||
goto parse_flag;
|
||||
|
||||
case oZeroKnowledgePasswordAuthentication:
|
||||
intptr = &options->zero_knowledge_password_authentication;
|
||||
goto parse_flag;
|
||||
|
||||
case oKbdInteractiveAuthentication:
|
||||
intptr = &options->kbd_interactive_authentication;
|
||||
goto parse_flag;
|
||||
@ -1465,6 +1467,13 @@ read_config_file(const char *filename, struct passwd *pw, const char *host,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
|
||||
int
|
||||
option_clear_or_none(const char *o)
|
||||
{
|
||||
return o == NULL || strcasecmp(o, "none") == 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initializes options to special values that indicate that they have not yet
|
||||
* been set. Read_config_file will only set options with this value. Options
|
||||
@ -1549,7 +1558,6 @@ initialize_options(Options * options)
|
||||
options->permit_local_command = -1;
|
||||
options->use_roaming = -1;
|
||||
options->visual_host_key = -1;
|
||||
options->zero_knowledge_password_authentication = -1;
|
||||
options->ip_qos_interactive = -1;
|
||||
options->ip_qos_bulk = -1;
|
||||
options->request_tty = -1;
|
||||
@ -1562,11 +1570,25 @@ initialize_options(Options * options)
|
||||
options->canonicalize_hostname = -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* A petite version of fill_default_options() that just fills the options
|
||||
* needed for hostname canonicalization to proceed.
|
||||
*/
|
||||
void
|
||||
fill_default_options_for_canonicalization(Options *options)
|
||||
{
|
||||
if (options->canonicalize_max_dots == -1)
|
||||
options->canonicalize_max_dots = 1;
|
||||
if (options->canonicalize_fallback_local == -1)
|
||||
options->canonicalize_fallback_local = 1;
|
||||
if (options->canonicalize_hostname == -1)
|
||||
options->canonicalize_hostname = SSH_CANONICALISE_NO;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called after processing other sources of option data, this fills those
|
||||
* options for which no value has been specified with their default values.
|
||||
*/
|
||||
|
||||
void
|
||||
fill_default_options(Options * options)
|
||||
{
|
||||
@ -1705,8 +1727,6 @@ fill_default_options(Options * options)
|
||||
options->use_roaming = 1;
|
||||
if (options->visual_host_key == -1)
|
||||
options->visual_host_key = 0;
|
||||
if (options->zero_knowledge_password_authentication == -1)
|
||||
options->zero_knowledge_password_authentication = 0;
|
||||
if (options->ip_qos_interactive == -1)
|
||||
options->ip_qos_interactive = IPTOS_LOWDELAY;
|
||||
if (options->ip_qos_bulk == -1)
|
||||
@ -1723,7 +1743,7 @@ fill_default_options(Options * options)
|
||||
options->canonicalize_hostname = SSH_CANONICALISE_NO;
|
||||
#define CLEAR_ON_NONE(v) \
|
||||
do { \
|
||||
if (v != NULL && strcasecmp(v, "none") == 0) { \
|
||||
if (option_clear_or_none(v)) { \
|
||||
free(v); \
|
||||
v = NULL; \
|
||||
} \
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: readconf.h,v 1.99 2013/10/16 22:49:38 djm Exp $ */
|
||||
/* $OpenBSD: readconf.h,v 1.101 2014/02/23 20:11:36 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -59,7 +59,6 @@ typedef struct {
|
||||
* authentication. */
|
||||
int kbd_interactive_authentication; /* Try keyboard-interactive auth. */
|
||||
char *kbd_interactive_devices; /* Keyboard-interactive auth devices. */
|
||||
int zero_knowledge_password_authentication; /* Try jpake */
|
||||
int batch_mode; /* Batch mode: do not ask for passwords. */
|
||||
int check_host_ip; /* Also keep track of keys for IP address */
|
||||
int strict_host_key_checking; /* Strict host key checking. */
|
||||
@ -177,12 +176,14 @@ typedef struct {
|
||||
|
||||
void initialize_options(Options *);
|
||||
void fill_default_options(Options *);
|
||||
void fill_default_options_for_canonicalization(Options *);
|
||||
int process_config_line(Options *, struct passwd *, const char *, char *,
|
||||
const char *, int, int *, int);
|
||||
int read_config_file(const char *, struct passwd *, const char *,
|
||||
Options *, int);
|
||||
int parse_forward(Forward *, const char *, int, int);
|
||||
int default_ssh_port(void);
|
||||
int option_clear_or_none(const char *);
|
||||
|
||||
void add_local_forward(Options *, const Forward *);
|
||||
void add_remote_forward(Options *, const Forward *);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: readpass.c,v 1.49 2013/05/17 00:13:14 djm Exp $ */
|
||||
/* $OpenBSD: readpass.c,v 1.50 2014/02/02 03:44:31 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2001 Markus Friedl. All rights reserved.
|
||||
*
|
||||
@ -99,13 +99,13 @@ ssh_askpass(char *askpass, const char *msg)
|
||||
break;
|
||||
signal(SIGCHLD, osigchld);
|
||||
if (ret == -1 || !WIFEXITED(status) || WEXITSTATUS(status) != 0) {
|
||||
memset(buf, 0, sizeof(buf));
|
||||
explicit_bzero(buf, sizeof(buf));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
buf[strcspn(buf, "\r\n")] = '\0';
|
||||
pass = xstrdup(buf);
|
||||
memset(buf, 0, sizeof(buf));
|
||||
explicit_bzero(buf, sizeof(buf));
|
||||
return pass;
|
||||
}
|
||||
|
||||
@ -162,7 +162,7 @@ read_passphrase(const char *prompt, int flags)
|
||||
}
|
||||
|
||||
ret = xstrdup(buf);
|
||||
memset(buf, 'x', sizeof buf);
|
||||
explicit_bzero(buf, sizeof(buf));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $OpenBSD: Makefile,v 1.67 2013/12/06 13:52:46 markus Exp $
|
||||
# $OpenBSD: Makefile,v 1.68 2014/01/25 04:35:32 dtucker Exp $
|
||||
|
||||
REGRESS_TARGETS= t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t-exec
|
||||
tests: $(REGRESS_TARGETS)
|
||||
@ -65,6 +65,7 @@ LTESTS= connect \
|
||||
forward-control \
|
||||
integrity \
|
||||
krl
|
||||
# dhgex \
|
||||
|
||||
INTEROP_TESTS= putty-transfer putty-ciphers putty-kex conch-ciphers
|
||||
#INTEROP_TESTS+=ssh-com ssh-com-client ssh-com-keygen ssh-com-sftp
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $OpenBSD: agent-ptrace.sh,v 1.1 2002/12/09 15:38:30 markus Exp $
|
||||
# $OpenBSD: agent-ptrace.sh,v 1.2 2014/02/27 21:21:25 djm Exp $
|
||||
# Placed in the Public Domain.
|
||||
|
||||
tid="disallow agent ptrace attach"
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $OpenBSD: agent.sh,v 1.9 2013/12/06 13:52:46 markus Exp $
|
||||
# $OpenBSD: agent.sh,v 1.10 2014/02/27 21:21:25 djm Exp $
|
||||
# Placed in the Public Domain.
|
||||
|
||||
tid="simple agent test"
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $OpenBSD: cert-hostkey.sh,v 1.8 2013/12/06 13:52:46 markus Exp $
|
||||
# $OpenBSD: cert-hostkey.sh,v 1.9 2014/01/26 10:22:10 djm Exp $
|
||||
# Placed in the Public Domain.
|
||||
|
||||
tid="certified host keys"
|
||||
|
54
regress/dhgex.sh
Executable file
54
regress/dhgex.sh
Executable file
@ -0,0 +1,54 @@
|
||||
# $OpenBSD: dhgex.sh,v 1.1 2014/01/25 04:35:32 dtucker Exp $
|
||||
# Placed in the Public Domain.
|
||||
|
||||
tid="dhgex"
|
||||
|
||||
LOG=${TEST_SSH_LOGFILE}
|
||||
rm -f ${LOG}
|
||||
|
||||
kexs=`${SSH} -Q kex | grep diffie-hellman-group-exchange`
|
||||
|
||||
ssh_test_dhgex()
|
||||
{
|
||||
bits="$1"; shift
|
||||
cipher="$1"; shift
|
||||
kex="$1"; shift
|
||||
|
||||
rm -f ${LOG}
|
||||
opts="-oKexAlgorithms=$kex -oCiphers=$cipher"
|
||||
groupsz="1024<$bits<8192"
|
||||
verbose "$tid bits $bits $kex $cipher"
|
||||
${SSH} ${opts} $@ -vvv -F ${OBJ}/ssh_proxy somehost true
|
||||
if [ $? -ne 0 ]; then
|
||||
fail "ssh failed ($@)"
|
||||
fi
|
||||
# check what we request
|
||||
grep "SSH2_MSG_KEX_DH_GEX_REQUEST($groupsz) sent" ${LOG} >/dev/null
|
||||
if [ $? != 0 ]; then
|
||||
got=`egrep "SSH2_MSG_KEX_DH_GEX_REQUEST(.*) sent" ${LOG}`
|
||||
fail "$tid unexpected GEX sizes, expected $groupsz, got $got"
|
||||
fi
|
||||
# check what we got (depends on contents of system moduli file)
|
||||
gotbits="`awk '/bits set:/{print $4}' ${LOG} | head -1 | cut -f2 -d/`"
|
||||
if [ "$gotbits" -lt "$bits" ]; then
|
||||
fatal "$tid expected $bits bit group, got $gotbits"
|
||||
fi
|
||||
}
|
||||
|
||||
check()
|
||||
{
|
||||
bits="$1"; shift
|
||||
|
||||
for c in $@; do
|
||||
for k in $kexs; do
|
||||
ssh_test_dhgex $bits $c $k
|
||||
done
|
||||
done
|
||||
}
|
||||
|
||||
#check 2048 3des-cbc
|
||||
check 3072 `${SSH} -Q cipher | grep 128`
|
||||
check 3072 arcfour blowfish-cbc
|
||||
check 7680 `${SSH} -Q cipher | grep 192`
|
||||
check 8192 `${SSH} -Q cipher | grep 256`
|
||||
check 8192 rijndael-cbc@lysator.liu.se chacha20-poly1305@openssh.com
|
@ -1,3 +1,4 @@
|
||||
# $OpenBSD: host-expand.sh,v 1.3 2014/02/27 23:17:41 djm Exp $
|
||||
# Placed in the Public Domain.
|
||||
|
||||
tid="expand %h and %n"
|
||||
|
@ -1,9 +1,11 @@
|
||||
# $OpenBSD: login-timeout.sh,v 1.5 2013/05/17 10:23:52 dtucker Exp $
|
||||
# $OpenBSD: login-timeout.sh,v 1.6 2014/02/27 20:04:16 djm Exp $
|
||||
# Placed in the Public Domain.
|
||||
|
||||
tid="connect after login grace timeout"
|
||||
|
||||
trace "test login grace with privsep"
|
||||
cp $OBJ/sshd_config $OBJ/sshd_config.orig
|
||||
grep -vi LoginGraceTime $OBJ/sshd_config.orig > $OBJ/sshd_config
|
||||
echo "LoginGraceTime 10s" >> $OBJ/sshd_config
|
||||
echo "MaxStartups 1" >> $OBJ/sshd_config
|
||||
start_sshd
|
||||
|
@ -1,5 +1,5 @@
|
||||
#!/bin/sh
|
||||
# $OpenBSD: scp-ssh-wrapper.sh,v 1.2 2005/12/14 04:36:39 dtucker Exp $
|
||||
# $OpenBSD: scp-ssh-wrapper.sh,v 1.3 2014/01/26 10:49:17 djm Exp $
|
||||
# Placed in the Public Domain.
|
||||
|
||||
printname () {
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $OpenBSD: scp.sh,v 1.9 2013/05/17 10:35:43 dtucker Exp $
|
||||
# $OpenBSD: scp.sh,v 1.10 2014/01/26 10:49:17 djm Exp $
|
||||
# Placed in the Public Domain.
|
||||
|
||||
tid="scp"
|
||||
|
@ -23,6 +23,7 @@
|
||||
# include <sys/statvfs.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
void
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $OpenBSD: sftp-chroot.sh,v 1.2 2013/05/17 04:29:14 dtucker Exp $
|
||||
# $OpenBSD: sftp-chroot.sh,v 1.4 2014/01/20 00:00:30 dtucker Exp $
|
||||
# Placed in the Public Domain.
|
||||
|
||||
tid="sftp in chroot"
|
||||
@ -18,7 +18,8 @@ $SUDO sh -c "echo mekmitastdigoat > $PRIVDATA" || \
|
||||
start_sshd -oChrootDirectory=$CHROOT -oForceCommand="internal-sftp -d /"
|
||||
|
||||
verbose "test $tid: get"
|
||||
${SFTP} -qS "$SSH" -F $OBJ/ssh_config host:/${FILENAME} $COPY || \
|
||||
${SFTP} -S "$SSH" -F $OBJ/ssh_config host:/${FILENAME} $COPY \
|
||||
>>$TEST_REGRESS_LOGFILE 2>&1 || \
|
||||
fatal "Fetch ${FILENAME} failed"
|
||||
cmp $PRIVDATA $COPY || fail "$PRIVDATA $COPY differ"
|
||||
|
||||
|
10
rsa.c
10
rsa.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: rsa.c,v 1.30 2013/05/17 00:13:14 djm Exp $ */
|
||||
/* $OpenBSD: rsa.c,v 1.31 2014/02/02 03:44:31 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@ -94,8 +94,8 @@ rsa_public_encrypt(BIGNUM *out, BIGNUM *in, RSA *key)
|
||||
if (BN_bin2bn(outbuf, len, out) == NULL)
|
||||
fatal("rsa_public_encrypt: BN_bin2bn failed");
|
||||
|
||||
memset(outbuf, 0, olen);
|
||||
memset(inbuf, 0, ilen);
|
||||
explicit_bzero(outbuf, olen);
|
||||
explicit_bzero(inbuf, ilen);
|
||||
free(outbuf);
|
||||
free(inbuf);
|
||||
}
|
||||
@ -120,8 +120,8 @@ rsa_private_decrypt(BIGNUM *out, BIGNUM *in, RSA *key)
|
||||
if (BN_bin2bn(outbuf, len, out) == NULL)
|
||||
fatal("rsa_private_decrypt: BN_bin2bn failed");
|
||||
}
|
||||
memset(outbuf, 0, olen);
|
||||
memset(inbuf, 0, ilen);
|
||||
explicit_bzero(outbuf, olen);
|
||||
explicit_bzero(inbuf, ilen);
|
||||
free(outbuf);
|
||||
free(inbuf);
|
||||
return len;
|
||||
|
@ -94,10 +94,12 @@ ssh_sandbox_child(struct ssh_sandbox *box)
|
||||
fatal("can't limit stderr: %m");
|
||||
|
||||
cap_rights_init(&rights, CAP_READ, CAP_WRITE);
|
||||
if (cap_rights_limit(box->monitor->m_recvfd, &rights) == -1)
|
||||
if (cap_rights_limit(box->monitor->m_recvfd, &rights) < 0 &&
|
||||
errno != ENOSYS)
|
||||
fatal("%s: failed to limit the network socket", __func__);
|
||||
cap_rights_init(&rights, CAP_WRITE);
|
||||
if (cap_rights_limit(box->monitor->m_log_sendfd, &rights) == -1)
|
||||
if (cap_rights_limit(box->monitor->m_log_sendfd, &rights) < 0 &&
|
||||
errno != ENOSYS)
|
||||
fatal("%s: failed to limit the logging socket", __func__);
|
||||
if (cap_enter() < 0 && errno != ENOSYS)
|
||||
fatal("%s: failed to enter capability mode", __func__);
|
||||
|
@ -98,6 +98,9 @@ static const struct sock_filter preauth_insns[] = {
|
||||
SC_ALLOW(read),
|
||||
SC_ALLOW(write),
|
||||
SC_ALLOW(close),
|
||||
#ifdef __NR_shutdown /* not defined on archs that go via socketcall(2) */
|
||||
SC_ALLOW(shutdown),
|
||||
#endif
|
||||
SC_ALLOW(brk),
|
||||
SC_ALLOW(poll),
|
||||
#ifdef __NR__newselect
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: sandbox-systrace.c,v 1.7 2013/06/01 13:15:52 dtucker Exp $ */
|
||||
/* $OpenBSD: sandbox-systrace.c,v 1.9 2014/01/31 16:39:19 tedu Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011 Damien Miller <djm@mindrot.org>
|
||||
*
|
||||
@ -66,6 +66,7 @@ static const struct sandbox_policy preauth_policy[] = {
|
||||
{ SYS_munmap, SYSTR_POLICY_PERMIT },
|
||||
{ SYS_read, SYSTR_POLICY_PERMIT },
|
||||
{ SYS_select, SYSTR_POLICY_PERMIT },
|
||||
{ SYS_shutdown, SYSTR_POLICY_PERMIT },
|
||||
{ SYS_sigprocmask, SYSTR_POLICY_PERMIT },
|
||||
{ SYS_write, SYSTR_POLICY_PERMIT },
|
||||
{ -1, -1 }
|
||||
@ -141,7 +142,7 @@ ssh_sandbox_parent(struct ssh_sandbox *box, pid_t child_pid,
|
||||
box->systrace_fd, child_pid, strerror(errno));
|
||||
|
||||
/* Allocate and assign policy */
|
||||
bzero(&policy, sizeof(policy));
|
||||
memset(&policy, 0, sizeof(policy));
|
||||
policy.strp_op = SYSTR_POLICY_NEW;
|
||||
policy.strp_maxents = SYS_MAXSYSCALL;
|
||||
if (ioctl(box->systrace_fd, STRIOCPOLICY, &policy) == -1)
|
||||
|
668
schnorr.c
668
schnorr.c
@ -1,668 +0,0 @@
|
||||
/* $OpenBSD: schnorr.c,v 1.9 2014/01/09 23:20:00 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Implementation of Schnorr signatures / zero-knowledge proofs, based on
|
||||
* description 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
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/bn.h>
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "buffer.h"
|
||||
#include "log.h"
|
||||
|
||||
#include "schnorr.h"
|
||||
#include "digest.h"
|
||||
|
||||
#include "openbsd-compat/openssl-compat.h"
|
||||
|
||||
/* #define SCHNORR_DEBUG */ /* Privacy-violating debugging */
|
||||
/* #define SCHNORR_MAIN */ /* Include main() selftest */
|
||||
|
||||
#ifndef SCHNORR_DEBUG
|
||||
# define SCHNORR_DEBUG_BN(a)
|
||||
# define SCHNORR_DEBUG_BUF(a)
|
||||
#else
|
||||
# define SCHNORR_DEBUG_BN(a) debug3_bn a
|
||||
# define SCHNORR_DEBUG_BUF(a) debug3_buf a
|
||||
#endif /* SCHNORR_DEBUG */
|
||||
|
||||
/*
|
||||
* Calculate hash component of Schnorr signature H(g || g^v || g^x || id)
|
||||
* using the hash function defined by "hash_alg". Returns signature as
|
||||
* bignum or NULL on error.
|
||||
*/
|
||||
static BIGNUM *
|
||||
schnorr_hash(const BIGNUM *p, const BIGNUM *q, const BIGNUM *g,
|
||||
int hash_alg, const BIGNUM *g_v, const BIGNUM *g_x,
|
||||
const u_char *id, u_int idlen)
|
||||
{
|
||||
u_char *digest;
|
||||
u_int digest_len;
|
||||
BIGNUM *h;
|
||||
Buffer b;
|
||||
int success = -1;
|
||||
|
||||
if ((h = BN_new()) == NULL) {
|
||||
error("%s: BN_new", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
buffer_init(&b);
|
||||
|
||||
/* h = H(g || p || q || g^v || g^x || id) */
|
||||
buffer_put_bignum2(&b, g);
|
||||
buffer_put_bignum2(&b, p);
|
||||
buffer_put_bignum2(&b, q);
|
||||
buffer_put_bignum2(&b, g_v);
|
||||
buffer_put_bignum2(&b, g_x);
|
||||
buffer_put_string(&b, id, idlen);
|
||||
|
||||
SCHNORR_DEBUG_BUF((buffer_ptr(&b), buffer_len(&b),
|
||||
"%s: hashblob", __func__));
|
||||
if (hash_buffer(buffer_ptr(&b), buffer_len(&b), hash_alg,
|
||||
&digest, &digest_len) != 0) {
|
||||
error("%s: hash_buffer", __func__);
|
||||
goto out;
|
||||
}
|
||||
if (BN_bin2bn(digest, (int)digest_len, h) == NULL) {
|
||||
error("%s: BN_bin2bn", __func__);
|
||||
goto out;
|
||||
}
|
||||
success = 0;
|
||||
SCHNORR_DEBUG_BN((h, "%s: h = ", __func__));
|
||||
out:
|
||||
buffer_free(&b);
|
||||
bzero(digest, digest_len);
|
||||
free(digest);
|
||||
digest_len = 0;
|
||||
if (success == 0)
|
||||
return h;
|
||||
BN_clear_free(h);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate Schnorr signature to prove knowledge of private value 'x' used
|
||||
* in public exponent g^x, under group defined by 'grp_p', 'grp_q' and 'grp_g'
|
||||
* using the hash function "hash_alg".
|
||||
* 'idlen' bytes from 'id' will be included in the signature hash as an anti-
|
||||
* replay salt.
|
||||
*
|
||||
* On success, 0 is returned. The signature values are returned as *e_p
|
||||
* (g^v mod p) and *r_p (v - xh mod q). The caller must free these values.
|
||||
* On failure, -1 is returned.
|
||||
*/
|
||||
int
|
||||
schnorr_sign(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
|
||||
int hash_alg, const BIGNUM *x, const BIGNUM *g_x,
|
||||
const u_char *id, u_int idlen, BIGNUM **r_p, BIGNUM **e_p)
|
||||
{
|
||||
int success = -1;
|
||||
BIGNUM *h, *tmp, *v, *g_v, *r;
|
||||
BN_CTX *bn_ctx;
|
||||
|
||||
SCHNORR_DEBUG_BN((x, "%s: x = ", __func__));
|
||||
SCHNORR_DEBUG_BN((g_x, "%s: g_x = ", __func__));
|
||||
|
||||
/* Avoid degenerate cases: g^0 yields a spoofable signature */
|
||||
if (BN_cmp(g_x, BN_value_one()) <= 0) {
|
||||
error("%s: g_x < 1", __func__);
|
||||
return -1;
|
||||
}
|
||||
if (BN_cmp(g_x, grp_p) >= 0) {
|
||||
error("%s: g_x > g", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
h = g_v = r = tmp = v = NULL;
|
||||
if ((bn_ctx = BN_CTX_new()) == NULL) {
|
||||
error("%s: BN_CTX_new", __func__);
|
||||
goto out;
|
||||
}
|
||||
if ((g_v = BN_new()) == NULL ||
|
||||
(r = BN_new()) == NULL ||
|
||||
(tmp = BN_new()) == NULL) {
|
||||
error("%s: BN_new", __func__);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* v must be a random element of Zq, so 1 <= v < q
|
||||
* we also exclude v = 1, since g^1 looks dangerous
|
||||
*/
|
||||
if ((v = bn_rand_range_gt_one(grp_p)) == NULL) {
|
||||
error("%s: bn_rand_range2", __func__);
|
||||
goto out;
|
||||
}
|
||||
SCHNORR_DEBUG_BN((v, "%s: v = ", __func__));
|
||||
|
||||
/* g_v = g^v mod p */
|
||||
if (BN_mod_exp(g_v, grp_g, v, grp_p, bn_ctx) == -1) {
|
||||
error("%s: BN_mod_exp (g^v mod p)", __func__);
|
||||
goto out;
|
||||
}
|
||||
SCHNORR_DEBUG_BN((g_v, "%s: g_v = ", __func__));
|
||||
|
||||
/* h = H(g || g^v || g^x || id) */
|
||||
if ((h = schnorr_hash(grp_p, grp_q, grp_g, hash_alg, g_v, g_x,
|
||||
id, idlen)) == NULL) {
|
||||
error("%s: schnorr_hash failed", __func__);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* r = v - xh mod q */
|
||||
if (BN_mod_mul(tmp, x, h, grp_q, bn_ctx) == -1) {
|
||||
error("%s: BN_mod_mul (tmp = xv mod q)", __func__);
|
||||
goto out;
|
||||
}
|
||||
if (BN_mod_sub(r, v, tmp, grp_q, bn_ctx) == -1) {
|
||||
error("%s: BN_mod_mul (r = v - tmp)", __func__);
|
||||
goto out;
|
||||
}
|
||||
SCHNORR_DEBUG_BN((g_v, "%s: e = ", __func__));
|
||||
SCHNORR_DEBUG_BN((r, "%s: r = ", __func__));
|
||||
|
||||
*e_p = g_v;
|
||||
*r_p = r;
|
||||
|
||||
success = 0;
|
||||
out:
|
||||
BN_CTX_free(bn_ctx);
|
||||
if (h != NULL)
|
||||
BN_clear_free(h);
|
||||
if (v != NULL)
|
||||
BN_clear_free(v);
|
||||
BN_clear_free(tmp);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate Schnorr signature to prove knowledge of private value 'x' used
|
||||
* in public exponent g^x, under group defined by 'grp_p', 'grp_q' and 'grp_g'
|
||||
* using a SHA256 hash.
|
||||
* 'idlen' bytes from 'id' will be included in the signature hash as an anti-
|
||||
* replay salt.
|
||||
* On success, 0 is returned and *siglen bytes of signature are returned in
|
||||
* *sig (caller to free). Returns -1 on failure.
|
||||
*/
|
||||
int
|
||||
schnorr_sign_buf(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
|
||||
const BIGNUM *x, const BIGNUM *g_x, const u_char *id, u_int idlen,
|
||||
u_char **sig, u_int *siglen)
|
||||
{
|
||||
Buffer b;
|
||||
BIGNUM *r, *e;
|
||||
|
||||
if (schnorr_sign(grp_p, grp_q, grp_g, SSH_DIGEST_SHA256,
|
||||
x, g_x, id, idlen, &r, &e) != 0)
|
||||
return -1;
|
||||
|
||||
/* Signature is (e, r) */
|
||||
buffer_init(&b);
|
||||
/* XXX sigtype-hash as string? */
|
||||
buffer_put_bignum2(&b, e);
|
||||
buffer_put_bignum2(&b, r);
|
||||
*siglen = buffer_len(&b);
|
||||
*sig = xmalloc(*siglen);
|
||||
memcpy(*sig, buffer_ptr(&b), *siglen);
|
||||
SCHNORR_DEBUG_BUF((buffer_ptr(&b), buffer_len(&b),
|
||||
"%s: sigblob", __func__));
|
||||
buffer_free(&b);
|
||||
|
||||
BN_clear_free(r);
|
||||
BN_clear_free(e);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify Schnorr signature { r (v - xh mod q), e (g^v mod p) } against
|
||||
* public exponent g_x (g^x) under group defined by 'grp_p', 'grp_q' and
|
||||
* 'grp_g' using hash "hash_alg".
|
||||
* Signature hash will be salted with 'idlen' bytes from 'id'.
|
||||
* Returns -1 on failure, 0 on incorrect signature or 1 on matching signature.
|
||||
*/
|
||||
int
|
||||
schnorr_verify(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
|
||||
int hash_alg, const BIGNUM *g_x, const u_char *id, u_int idlen,
|
||||
const BIGNUM *r, const BIGNUM *e)
|
||||
{
|
||||
int success = -1;
|
||||
BIGNUM *h = NULL, *g_xh = NULL, *g_r = NULL, *gx_q = NULL;
|
||||
BIGNUM *expected = NULL;
|
||||
BN_CTX *bn_ctx;
|
||||
|
||||
SCHNORR_DEBUG_BN((g_x, "%s: g_x = ", __func__));
|
||||
|
||||
/* Avoid degenerate cases: g^0 yields a spoofable signature */
|
||||
if (BN_cmp(g_x, BN_value_one()) <= 0) {
|
||||
error("%s: g_x <= 1", __func__);
|
||||
return -1;
|
||||
}
|
||||
if (BN_cmp(g_x, grp_p) >= 0) {
|
||||
error("%s: g_x >= p", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
h = g_xh = g_r = expected = NULL;
|
||||
if ((bn_ctx = BN_CTX_new()) == NULL) {
|
||||
error("%s: BN_CTX_new", __func__);
|
||||
goto out;
|
||||
}
|
||||
if ((g_xh = BN_new()) == NULL ||
|
||||
(g_r = BN_new()) == NULL ||
|
||||
(gx_q = BN_new()) == NULL ||
|
||||
(expected = BN_new()) == NULL) {
|
||||
error("%s: BN_new", __func__);
|
||||
goto out;
|
||||
}
|
||||
|
||||
SCHNORR_DEBUG_BN((e, "%s: e = ", __func__));
|
||||
SCHNORR_DEBUG_BN((r, "%s: r = ", __func__));
|
||||
|
||||
/* gx_q = (g^x)^q must === 1 mod p */
|
||||
if (BN_mod_exp(gx_q, g_x, grp_q, grp_p, bn_ctx) == -1) {
|
||||
error("%s: BN_mod_exp (g_x^q mod p)", __func__);
|
||||
goto out;
|
||||
}
|
||||
if (BN_cmp(gx_q, BN_value_one()) != 0) {
|
||||
error("%s: Invalid signature (g^x)^q != 1 mod p", __func__);
|
||||
goto out;
|
||||
}
|
||||
|
||||
SCHNORR_DEBUG_BN((g_xh, "%s: g_xh = ", __func__));
|
||||
/* h = H(g || g^v || g^x || id) */
|
||||
if ((h = schnorr_hash(grp_p, grp_q, grp_g, hash_alg, e, g_x,
|
||||
id, idlen)) == NULL) {
|
||||
error("%s: schnorr_hash failed", __func__);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* g_xh = (g^x)^h */
|
||||
if (BN_mod_exp(g_xh, g_x, h, grp_p, bn_ctx) == -1) {
|
||||
error("%s: BN_mod_exp (g_x^h mod p)", __func__);
|
||||
goto out;
|
||||
}
|
||||
SCHNORR_DEBUG_BN((g_xh, "%s: g_xh = ", __func__));
|
||||
|
||||
/* g_r = g^r */
|
||||
if (BN_mod_exp(g_r, grp_g, r, grp_p, bn_ctx) == -1) {
|
||||
error("%s: BN_mod_exp (g_x^h mod p)", __func__);
|
||||
goto out;
|
||||
}
|
||||
SCHNORR_DEBUG_BN((g_r, "%s: g_r = ", __func__));
|
||||
|
||||
/* expected = g^r * g_xh */
|
||||
if (BN_mod_mul(expected, g_r, g_xh, grp_p, bn_ctx) == -1) {
|
||||
error("%s: BN_mod_mul (expected = g_r mod p)", __func__);
|
||||
goto out;
|
||||
}
|
||||
SCHNORR_DEBUG_BN((expected, "%s: expected = ", __func__));
|
||||
|
||||
/* Check e == expected */
|
||||
success = BN_cmp(expected, e) == 0;
|
||||
out:
|
||||
BN_CTX_free(bn_ctx);
|
||||
if (h != NULL)
|
||||
BN_clear_free(h);
|
||||
if (gx_q != NULL)
|
||||
BN_clear_free(gx_q);
|
||||
if (g_xh != NULL)
|
||||
BN_clear_free(g_xh);
|
||||
if (g_r != NULL)
|
||||
BN_clear_free(g_r);
|
||||
if (expected != NULL)
|
||||
BN_clear_free(expected);
|
||||
return success;
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify Schnorr signature 'sig' of length 'siglen' against public exponent
|
||||
* g_x (g^x) under group defined by 'grp_p', 'grp_q' and 'grp_g' using a
|
||||
* SHA256 hash.
|
||||
* Signature hash will be salted with 'idlen' bytes from 'id'.
|
||||
* Returns -1 on failure, 0 on incorrect signature or 1 on matching signature.
|
||||
*/
|
||||
int
|
||||
schnorr_verify_buf(const BIGNUM *grp_p, const BIGNUM *grp_q,
|
||||
const BIGNUM *grp_g,
|
||||
const BIGNUM *g_x, const u_char *id, u_int idlen,
|
||||
const u_char *sig, u_int siglen)
|
||||
{
|
||||
Buffer b;
|
||||
int ret = -1;
|
||||
u_int rlen;
|
||||
BIGNUM *r, *e;
|
||||
|
||||
e = r = NULL;
|
||||
if ((e = BN_new()) == NULL ||
|
||||
(r = BN_new()) == NULL) {
|
||||
error("%s: BN_new", __func__);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Extract g^v and r from signature blob */
|
||||
buffer_init(&b);
|
||||
buffer_append(&b, sig, siglen);
|
||||
SCHNORR_DEBUG_BUF((buffer_ptr(&b), buffer_len(&b),
|
||||
"%s: sigblob", __func__));
|
||||
buffer_get_bignum2(&b, e);
|
||||
buffer_get_bignum2(&b, r);
|
||||
rlen = buffer_len(&b);
|
||||
buffer_free(&b);
|
||||
if (rlen != 0) {
|
||||
error("%s: remaining bytes in signature %d", __func__, rlen);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = schnorr_verify(grp_p, grp_q, grp_g, SSH_DIGEST_SHA256,
|
||||
g_x, id, idlen, r, e);
|
||||
out:
|
||||
BN_clear_free(e);
|
||||
BN_clear_free(r);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Helper functions */
|
||||
|
||||
/*
|
||||
* Generate uniformly distributed random number in range (1, high).
|
||||
* Return number on success, NULL on failure.
|
||||
*/
|
||||
BIGNUM *
|
||||
bn_rand_range_gt_one(const BIGNUM *high)
|
||||
{
|
||||
BIGNUM *r, *tmp;
|
||||
int success = -1;
|
||||
|
||||
if ((tmp = BN_new()) == NULL) {
|
||||
error("%s: BN_new", __func__);
|
||||
return NULL;
|
||||
}
|
||||
if ((r = BN_new()) == NULL) {
|
||||
error("%s: BN_new failed", __func__);
|
||||
goto out;
|
||||
}
|
||||
if (BN_set_word(tmp, 2) != 1) {
|
||||
error("%s: BN_set_word(tmp, 2)", __func__);
|
||||
goto out;
|
||||
}
|
||||
if (BN_sub(tmp, high, tmp) == -1) {
|
||||
error("%s: BN_sub failed (tmp = high - 2)", __func__);
|
||||
goto out;
|
||||
}
|
||||
if (BN_rand_range(r, tmp) == -1) {
|
||||
error("%s: BN_rand_range failed", __func__);
|
||||
goto out;
|
||||
}
|
||||
if (BN_set_word(tmp, 2) != 1) {
|
||||
error("%s: BN_set_word(tmp, 2)", __func__);
|
||||
goto out;
|
||||
}
|
||||
if (BN_add(r, r, tmp) == -1) {
|
||||
error("%s: BN_add failed (r = r + 2)", __func__);
|
||||
goto out;
|
||||
}
|
||||
success = 0;
|
||||
out:
|
||||
BN_clear_free(tmp);
|
||||
if (success == 0)
|
||||
return r;
|
||||
BN_clear_free(r);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* XXX convert all callers of this to use ssh_digest_memory() directly */
|
||||
/*
|
||||
* Hash contents of buffer 'b' with hash 'md'. Returns 0 on success,
|
||||
* with digest via 'digestp' (caller to free) and length via 'lenp'.
|
||||
* Returns -1 on failure.
|
||||
*/
|
||||
int
|
||||
hash_buffer(const u_char *buf, u_int len, int hash_alg,
|
||||
u_char **digestp, u_int *lenp)
|
||||
{
|
||||
u_char digest[SSH_DIGEST_MAX_LENGTH];
|
||||
u_int digest_len = ssh_digest_bytes(hash_alg);
|
||||
|
||||
if (digest_len == 0) {
|
||||
error("%s: invalid hash", __func__);
|
||||
return -1;
|
||||
}
|
||||
if (ssh_digest_memory(hash_alg, buf, len, digest, digest_len) != 0) {
|
||||
error("%s: digest_memory failed", __func__);
|
||||
return -1;
|
||||
}
|
||||
*digestp = xmalloc(digest_len);
|
||||
*lenp = digest_len;
|
||||
memcpy(*digestp, digest, *lenp);
|
||||
bzero(digest, sizeof(digest));
|
||||
digest_len = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* print formatted string followed by bignum */
|
||||
void
|
||||
debug3_bn(const BIGNUM *n, const char *fmt, ...)
|
||||
{
|
||||
char *out, *h;
|
||||
va_list args;
|
||||
int ret;
|
||||
|
||||
out = NULL;
|
||||
va_start(args, fmt);
|
||||
ret = vasprintf(&out, fmt, args);
|
||||
va_end(args);
|
||||
if (ret == -1 || out == NULL)
|
||||
fatal("%s: vasprintf failed", __func__);
|
||||
|
||||
if (n == NULL)
|
||||
debug3("%s(null)", out);
|
||||
else {
|
||||
h = BN_bn2hex(n);
|
||||
debug3("%s0x%s", out, h);
|
||||
free(h);
|
||||
}
|
||||
free(out);
|
||||
}
|
||||
|
||||
/* print formatted string followed by buffer contents in hex */
|
||||
void
|
||||
debug3_buf(const u_char *buf, u_int len, const char *fmt, ...)
|
||||
{
|
||||
char *out, h[65];
|
||||
u_int i, j;
|
||||
va_list args;
|
||||
int ret;
|
||||
|
||||
out = NULL;
|
||||
va_start(args, fmt);
|
||||
ret = vasprintf(&out, fmt, args);
|
||||
va_end(args);
|
||||
if (ret == -1 || out == NULL)
|
||||
fatal("%s: vasprintf failed", __func__);
|
||||
|
||||
debug3("%s length %u%s", out, len, buf == NULL ? " (null)" : "");
|
||||
free(out);
|
||||
if (buf == NULL)
|
||||
return;
|
||||
|
||||
*h = '\0';
|
||||
for (i = j = 0; i < len; i++) {
|
||||
snprintf(h + j, sizeof(h) - j, "%02x", buf[i]);
|
||||
j += 2;
|
||||
if (j >= sizeof(h) - 1 || i == len - 1) {
|
||||
debug3(" %s", h);
|
||||
*h = '\0';
|
||||
j = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Construct a MODP group from hex strings p (which must be a safe
|
||||
* prime) and g, automatically calculating subgroup q as (p / 2)
|
||||
*/
|
||||
struct modp_group *
|
||||
modp_group_from_g_and_safe_p(const char *grp_g, const char *grp_p)
|
||||
{
|
||||
struct modp_group *ret;
|
||||
|
||||
ret = xcalloc(1, sizeof(*ret));
|
||||
ret->p = ret->q = ret->g = NULL;
|
||||
if (BN_hex2bn(&ret->p, grp_p) == 0 ||
|
||||
BN_hex2bn(&ret->g, grp_g) == 0)
|
||||
fatal("%s: BN_hex2bn", __func__);
|
||||
/* Subgroup order is p/2 (p is a safe prime) */
|
||||
if ((ret->q = BN_new()) == NULL)
|
||||
fatal("%s: BN_new", __func__);
|
||||
if (BN_rshift1(ret->q, ret->p) != 1)
|
||||
fatal("%s: BN_rshift1", __func__);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
modp_group_free(struct modp_group *grp)
|
||||
{
|
||||
if (grp->g != NULL)
|
||||
BN_clear_free(grp->g);
|
||||
if (grp->p != NULL)
|
||||
BN_clear_free(grp->p);
|
||||
if (grp->q != NULL)
|
||||
BN_clear_free(grp->q);
|
||||
bzero(grp, sizeof(*grp));
|
||||
free(grp);
|
||||
}
|
||||
|
||||
/* main() function for self-test */
|
||||
|
||||
#ifdef SCHNORR_MAIN
|
||||
static void
|
||||
schnorr_selftest_one(const BIGNUM *grp_p, const BIGNUM *grp_q,
|
||||
const BIGNUM *grp_g, const BIGNUM *x)
|
||||
{
|
||||
BIGNUM *g_x;
|
||||
u_char *sig;
|
||||
u_int siglen;
|
||||
BN_CTX *bn_ctx;
|
||||
|
||||
if ((bn_ctx = BN_CTX_new()) == NULL)
|
||||
fatal("%s: BN_CTX_new", __func__);
|
||||
if ((g_x = BN_new()) == NULL)
|
||||
fatal("%s: BN_new", __func__);
|
||||
|
||||
if (BN_mod_exp(g_x, grp_g, x, grp_p, bn_ctx) == -1)
|
||||
fatal("%s: g_x", __func__);
|
||||
if (schnorr_sign_buf(grp_p, grp_q, grp_g, x, g_x, "junk", 4,
|
||||
&sig, &siglen))
|
||||
fatal("%s: schnorr_sign", __func__);
|
||||
if (schnorr_verify_buf(grp_p, grp_q, grp_g, g_x, "junk", 4,
|
||||
sig, siglen) != 1)
|
||||
fatal("%s: verify fail", __func__);
|
||||
if (schnorr_verify_buf(grp_p, grp_q, grp_g, g_x, "JUNK", 4,
|
||||
sig, siglen) != 0)
|
||||
fatal("%s: verify should have failed (bad ID)", __func__);
|
||||
sig[4] ^= 1;
|
||||
if (schnorr_verify_buf(grp_p, grp_q, grp_g, g_x, "junk", 4,
|
||||
sig, siglen) != 0)
|
||||
fatal("%s: verify should have failed (bit error)", __func__);
|
||||
free(sig);
|
||||
BN_free(g_x);
|
||||
BN_CTX_free(bn_ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
schnorr_selftest(void)
|
||||
{
|
||||
BIGNUM *x;
|
||||
struct modp_group *grp;
|
||||
u_int i;
|
||||
char *hh;
|
||||
|
||||
grp = jpake_default_group();
|
||||
if ((x = BN_new()) == NULL)
|
||||
fatal("%s: BN_new", __func__);
|
||||
SCHNORR_DEBUG_BN((grp->p, "%s: grp->p = ", __func__));
|
||||
SCHNORR_DEBUG_BN((grp->q, "%s: grp->q = ", __func__));
|
||||
SCHNORR_DEBUG_BN((grp->g, "%s: grp->g = ", __func__));
|
||||
|
||||
/* [1, 20) */
|
||||
for (i = 1; i < 20; i++) {
|
||||
printf("x = %u\n", i);
|
||||
fflush(stdout);
|
||||
if (BN_set_word(x, i) != 1)
|
||||
fatal("%s: set x word", __func__);
|
||||
schnorr_selftest_one(grp->p, grp->q, grp->g, x);
|
||||
}
|
||||
|
||||
/* 100 x random [0, p) */
|
||||
for (i = 0; i < 100; i++) {
|
||||
if (BN_rand_range(x, grp->p) != 1)
|
||||
fatal("%s: BN_rand_range", __func__);
|
||||
hh = BN_bn2hex(x);
|
||||
printf("x = (random) 0x%s\n", hh);
|
||||
free(hh);
|
||||
fflush(stdout);
|
||||
schnorr_selftest_one(grp->p, grp->q, grp->g, x);
|
||||
}
|
||||
|
||||
/* [q-20, q) */
|
||||
if (BN_set_word(x, 20) != 1)
|
||||
fatal("%s: BN_set_word (x = 20)", __func__);
|
||||
if (BN_sub(x, grp->q, x) != 1)
|
||||
fatal("%s: BN_sub (q - x)", __func__);
|
||||
for (i = 0; i < 19; i++) {
|
||||
hh = BN_bn2hex(x);
|
||||
printf("x = (q - %d) 0x%s\n", 20 - i, hh);
|
||||
free(hh);
|
||||
fflush(stdout);
|
||||
schnorr_selftest_one(grp->p, grp->q, grp->g, x);
|
||||
if (BN_add(x, x, BN_value_one()) != 1)
|
||||
fatal("%s: BN_add (x + 1)", __func__);
|
||||
}
|
||||
BN_free(x);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
log_init(argv[0], SYSLOG_LEVEL_DEBUG3, SYSLOG_FACILITY_USER, 1);
|
||||
|
||||
schnorr_selftest();
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
60
schnorr.h
60
schnorr.h
@ -1,60 +0,0 @@
|
||||
/* $OpenBSD: schnorr.h,v 1.2 2014/01/09 23:20:00 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009 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.
|
||||
*/
|
||||
|
||||
#ifndef SCHNORR_H
|
||||
#define SCHNORR_H
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <openssl/bn.h>
|
||||
|
||||
struct modp_group {
|
||||
BIGNUM *p, *q, *g;
|
||||
};
|
||||
|
||||
BIGNUM *bn_rand_range_gt_one(const BIGNUM *high);
|
||||
int hash_buffer(const u_char *, u_int, int, u_char **, u_int *);
|
||||
void debug3_bn(const BIGNUM *, const char *, ...)
|
||||
__attribute__((__nonnull__ (2)))
|
||||
__attribute__((format(printf, 2, 3)));
|
||||
void debug3_buf(const u_char *, u_int, const char *, ...)
|
||||
__attribute__((__nonnull__ (3)))
|
||||
__attribute__((format(printf, 3, 4)));
|
||||
struct modp_group *modp_group_from_g_and_safe_p(const char *, const char *);
|
||||
void modp_group_free(struct modp_group *);
|
||||
|
||||
/* Signature and verification functions */
|
||||
int
|
||||
schnorr_sign(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
|
||||
int hash_alg, const BIGNUM *x, const BIGNUM *g_x,
|
||||
const u_char *id, u_int idlen, BIGNUM **r_p, BIGNUM **e_p);
|
||||
int
|
||||
schnorr_sign_buf(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
|
||||
const BIGNUM *x, const BIGNUM *g_x, const u_char *id, u_int idlen,
|
||||
u_char **sig, u_int *siglen);
|
||||
int
|
||||
schnorr_verify(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
|
||||
int hash_alg, const BIGNUM *g_x, const u_char *id, u_int idlen,
|
||||
const BIGNUM *r, const BIGNUM *e);
|
||||
int
|
||||
schnorr_verify_buf(const BIGNUM *grp_p, const BIGNUM *grp_q,
|
||||
const BIGNUM *grp_g,
|
||||
const BIGNUM *g_x, const u_char *id, u_int idlen,
|
||||
const u_char *sig, u_int siglen);
|
||||
|
||||
#endif /* JPAKE_H */
|
||||
|
2
scp.0
2
scp.0
@ -160,4 +160,4 @@ AUTHORS
|
||||
Timo Rinne <tri@iki.fi>
|
||||
Tatu Ylonen <ylo@cs.hut.fi>
|
||||
|
||||
OpenBSD 5.4 October 20, 2013 OpenBSD 5.4
|
||||
OpenBSD 5.5 October 20, 2013 OpenBSD 5.5
|
||||
|
21
servconf.c
21
servconf.c
@ -1,5 +1,5 @@
|
||||
|
||||
/* $OpenBSD: servconf.c,v 1.248 2013/12/06 13:39:49 markus Exp $ */
|
||||
/* $OpenBSD: servconf.c,v 1.249 2014/01/29 06:18:35 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
@ -147,7 +147,6 @@ initialize_server_options(ServerOptions *options)
|
||||
options->chroot_directory = NULL;
|
||||
options->authorized_keys_command = NULL;
|
||||
options->authorized_keys_command_user = NULL;
|
||||
options->zero_knowledge_password_authentication = -1;
|
||||
options->revoked_keys_file = NULL;
|
||||
options->trusted_user_ca_keys = NULL;
|
||||
options->authorized_principals_file = NULL;
|
||||
@ -295,8 +294,6 @@ fill_default_server_options(ServerOptions *options)
|
||||
}
|
||||
if (options->permit_tun == -1)
|
||||
options->permit_tun = SSH_TUNMODE_NO;
|
||||
if (options->zero_knowledge_password_authentication == -1)
|
||||
options->zero_knowledge_password_authentication = 0;
|
||||
if (options->ip_qos_interactive == -1)
|
||||
options->ip_qos_interactive = IPTOS_LOWDELAY;
|
||||
if (options->ip_qos_bulk == -1)
|
||||
@ -346,7 +343,7 @@ typedef enum {
|
||||
sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
|
||||
sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
|
||||
sUsePrivilegeSeparation, sAllowAgentForwarding,
|
||||
sZeroKnowledgePasswordAuthentication, sHostCertificate,
|
||||
sHostCertificate,
|
||||
sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile,
|
||||
sKexAlgorithms, sIPQoS, sVersionAddendum,
|
||||
sAuthorizedKeysCommand, sAuthorizedKeysCommandUser,
|
||||
@ -418,11 +415,6 @@ static struct {
|
||||
{ "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL },
|
||||
{ "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL },
|
||||
{ "skeyauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, /* alias */
|
||||
#ifdef JPAKE
|
||||
{ "zeroknowledgepasswordauthentication", sZeroKnowledgePasswordAuthentication, SSHCFG_ALL },
|
||||
#else
|
||||
{ "zeroknowledgepasswordauthentication", sUnsupported, SSHCFG_ALL },
|
||||
#endif
|
||||
{ "checkmail", sDeprecated, SSHCFG_GLOBAL },
|
||||
{ "listenaddress", sListenAddress, SSHCFG_GLOBAL },
|
||||
{ "addressfamily", sAddressFamily, SSHCFG_GLOBAL },
|
||||
@ -1102,10 +1094,6 @@ process_server_config_line(ServerOptions *options, char *line,
|
||||
intptr = &options->password_authentication;
|
||||
goto parse_flag;
|
||||
|
||||
case sZeroKnowledgePasswordAuthentication:
|
||||
intptr = &options->zero_knowledge_password_authentication;
|
||||
goto parse_flag;
|
||||
|
||||
case sKbdInteractiveAuthentication:
|
||||
intptr = &options->kbd_interactive_authentication;
|
||||
goto parse_flag;
|
||||
@ -1767,7 +1755,6 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
|
||||
M_CP_INTOPT(hostbased_authentication);
|
||||
M_CP_INTOPT(hostbased_uses_name_from_packet_only);
|
||||
M_CP_INTOPT(kbd_interactive_authentication);
|
||||
M_CP_INTOPT(zero_knowledge_password_authentication);
|
||||
M_CP_INTOPT(permit_root_login);
|
||||
M_CP_INTOPT(permit_empty_passwd);
|
||||
|
||||
@ -2009,10 +1996,6 @@ dump_config(ServerOptions *o)
|
||||
#ifdef GSSAPI
|
||||
dump_cfg_fmtint(sGssAuthentication, o->gss_authentication);
|
||||
dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds);
|
||||
#endif
|
||||
#ifdef JPAKE
|
||||
dump_cfg_fmtint(sZeroKnowledgePasswordAuthentication,
|
||||
o->zero_knowledge_password_authentication);
|
||||
#endif
|
||||
dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication);
|
||||
dump_cfg_fmtint(sKbdInteractiveAuthentication,
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: servconf.h,v 1.111 2013/12/05 01:16:41 djm Exp $ */
|
||||
/* $OpenBSD: servconf.h,v 1.112 2014/01/29 06:18:35 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -117,8 +117,6 @@ typedef struct {
|
||||
* authentication. */
|
||||
int kbd_interactive_authentication; /* If true, permit */
|
||||
int challenge_response_authentication;
|
||||
int zero_knowledge_password_authentication;
|
||||
/* If true, permit jpake auth */
|
||||
int permit_empty_passwd; /* If false, do not permit empty
|
||||
* passwords. */
|
||||
int permit_user_env; /* If true, read ~/.ssh/environment */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: serverloop.c,v 1.169 2013/12/19 00:19:12 dtucker Exp $ */
|
||||
/* $OpenBSD: serverloop.c,v 1.170 2014/02/02 03:44:31 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@ -920,7 +920,7 @@ server_input_stdin_data(int type, u_int32_t seq, void *ctxt)
|
||||
data = packet_get_string(&data_len);
|
||||
packet_check_eom();
|
||||
buffer_append(&stdin_buffer, data, data_len);
|
||||
memset(data, 0, data_len);
|
||||
explicit_bzero(data, data_len);
|
||||
free(data);
|
||||
}
|
||||
|
||||
|
13
session.c
13
session.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: session.c,v 1.269 2014/01/18 09:36:26 dtucker Exp $ */
|
||||
/* $OpenBSD: session.c,v 1.270 2014/01/31 16:39:19 tedu Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
@ -978,6 +978,11 @@ child_set_env(char ***envp, u_int *envsizep, const char *name,
|
||||
u_int envsize;
|
||||
u_int i, namelen;
|
||||
|
||||
if (strchr(name, '=') != NULL) {
|
||||
error("Invalid environment variable \"%.100s\"", name);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we're passed an uninitialized list, allocate a single null
|
||||
* entry before continuing.
|
||||
@ -1889,7 +1894,7 @@ session_unused(int id)
|
||||
fatal("%s: insane session id %d (max %d nalloc %d)",
|
||||
__func__, id, options.max_sessions, sessions_nalloc);
|
||||
}
|
||||
bzero(&sessions[id], sizeof(*sessions));
|
||||
memset(&sessions[id], 0, sizeof(*sessions));
|
||||
sessions[id].self = id;
|
||||
sessions[id].used = 0;
|
||||
sessions[id].chanid = -1;
|
||||
@ -2225,8 +2230,8 @@ session_env_req(Session *s)
|
||||
char *name, *val;
|
||||
u_int name_len, val_len, i;
|
||||
|
||||
name = packet_get_string(&name_len);
|
||||
val = packet_get_string(&val_len);
|
||||
name = packet_get_cstring(&name_len);
|
||||
val = packet_get_cstring(&val_len);
|
||||
packet_check_eom();
|
||||
|
||||
/* Don't set too many environment variables */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: sftp-client.c,v 1.113 2014/01/17 00:21:06 djm Exp $ */
|
||||
/* $OpenBSD: sftp-client.c,v 1.114 2014/01/31 16:39:19 tedu Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
|
||||
*
|
||||
@ -310,7 +310,7 @@ get_decode_statvfs(struct sftp_conn *conn, struct sftp_statvfs *st,
|
||||
SSH2_FXP_EXTENDED_REPLY, type);
|
||||
}
|
||||
|
||||
bzero(st, sizeof(*st));
|
||||
memset(st, 0, sizeof(*st));
|
||||
st->f_bsize = buffer_get_int64(&msg);
|
||||
st->f_frsize = buffer_get_int64(&msg);
|
||||
st->f_blocks = buffer_get_int64(&msg);
|
||||
|
@ -92,4 +92,4 @@ HISTORY
|
||||
AUTHORS
|
||||
Markus Friedl <markus@openbsd.org>
|
||||
|
||||
OpenBSD 5.4 October 14, 2013 OpenBSD 5.4
|
||||
OpenBSD 5.5 October 14, 2013 OpenBSD 5.5
|
||||
|
2
sftp.0
2
sftp.0
@ -367,4 +367,4 @@ SEE ALSO
|
||||
T. Ylonen and S. Lehtinen, SSH File Transfer Protocol, draft-ietf-secsh-
|
||||
filexfer-00.txt, January 2001, work in progress material.
|
||||
|
||||
OpenBSD 5.4 October 20, 2013 OpenBSD 5.4
|
||||
OpenBSD 5.5 October 20, 2013 OpenBSD 5.5
|
||||
|
@ -120,4 +120,4 @@ AUTHORS
|
||||
created OpenSSH. Markus Friedl contributed the support for SSH protocol
|
||||
versions 1.5 and 2.0.
|
||||
|
||||
OpenBSD 5.4 December 7, 2013 OpenBSD 5.4
|
||||
OpenBSD 5.5 December 7, 2013 OpenBSD 5.5
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: ssh-add.c,v 1.108 2013/12/19 00:10:30 djm Exp $ */
|
||||
/* $OpenBSD: ssh-add.c,v 1.109 2014/02/02 03:44:31 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@ -90,7 +90,7 @@ static void
|
||||
clear_pass(void)
|
||||
{
|
||||
if (pass) {
|
||||
memset(pass, 0, strlen(pass));
|
||||
explicit_bzero(pass, strlen(pass));
|
||||
free(pass);
|
||||
pass = NULL;
|
||||
}
|
||||
@ -366,7 +366,7 @@ lock_agent(AuthenticationConnection *ac, int lock)
|
||||
fprintf(stderr, "Passwords do not match.\n");
|
||||
passok = 0;
|
||||
}
|
||||
memset(p2, 0, strlen(p2));
|
||||
explicit_bzero(p2, strlen(p2));
|
||||
free(p2);
|
||||
}
|
||||
if (passok && ssh_lock_agent(ac, lock, p1)) {
|
||||
@ -374,7 +374,7 @@ lock_agent(AuthenticationConnection *ac, int lock)
|
||||
ret = 0;
|
||||
} else
|
||||
fprintf(stderr, "Failed to %slock agent.\n", lock ? "" : "un");
|
||||
memset(p1, 0, strlen(p1));
|
||||
explicit_bzero(p1, strlen(p1));
|
||||
free(p1);
|
||||
return (ret);
|
||||
}
|
||||
|
@ -125,4 +125,4 @@ AUTHORS
|
||||
created OpenSSH. Markus Friedl contributed the support for SSH protocol
|
||||
versions 1.5 and 2.0.
|
||||
|
||||
OpenBSD 5.4 December 7, 2013 OpenBSD 5.4
|
||||
OpenBSD 5.5 December 7, 2013 OpenBSD 5.5
|
||||
|
20
ssh-agent.c
20
ssh-agent.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: ssh-agent.c,v 1.181 2013/12/19 01:19:41 djm Exp $ */
|
||||
/* $OpenBSD: ssh-agent.c,v 1.183 2014/02/02 03:44:31 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@ -50,7 +50,6 @@
|
||||
#include "openbsd-compat/sys-queue.h"
|
||||
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/md5.h>
|
||||
#include "openbsd-compat/openssl-compat.h"
|
||||
|
||||
#include <errno.h>
|
||||
@ -75,6 +74,7 @@
|
||||
#include "compat.h"
|
||||
#include "log.h"
|
||||
#include "misc.h"
|
||||
#include "digest.h"
|
||||
|
||||
#ifdef ENABLE_PKCS11
|
||||
#include "ssh-pkcs11.h"
|
||||
@ -248,7 +248,7 @@ process_authentication_challenge1(SocketEntry *e)
|
||||
Identity *id;
|
||||
int i, len;
|
||||
Buffer msg;
|
||||
MD5_CTX md;
|
||||
struct ssh_digest_ctx *md;
|
||||
Key *key;
|
||||
|
||||
buffer_init(&msg);
|
||||
@ -284,10 +284,12 @@ process_authentication_challenge1(SocketEntry *e)
|
||||
}
|
||||
memset(buf, 0, 32);
|
||||
BN_bn2bin(challenge, buf + 32 - len);
|
||||
MD5_Init(&md);
|
||||
MD5_Update(&md, buf, 32);
|
||||
MD5_Update(&md, session_id, 16);
|
||||
MD5_Final(mdbuf, &md);
|
||||
if ((md = ssh_digest_start(SSH_DIGEST_MD5)) == NULL ||
|
||||
ssh_digest_update(md, buf, 32) < 0 ||
|
||||
ssh_digest_update(md, session_id, 16) < 0 ||
|
||||
ssh_digest_final(md, mdbuf, sizeof(mdbuf)) < 0)
|
||||
fatal("%s: md5 failed", __func__);
|
||||
ssh_digest_free(md);
|
||||
|
||||
/* Send the response. */
|
||||
buffer_put_char(&msg, SSH_AGENT_RSA_RESPONSE);
|
||||
@ -552,7 +554,7 @@ process_lock_agent(SocketEntry *e, int lock)
|
||||
passwd = buffer_get_string(&e->request, NULL);
|
||||
if (locked && !lock && strcmp(passwd, lock_passwd) == 0) {
|
||||
locked = 0;
|
||||
memset(lock_passwd, 0, strlen(lock_passwd));
|
||||
explicit_bzero(lock_passwd, strlen(lock_passwd));
|
||||
free(lock_passwd);
|
||||
lock_passwd = NULL;
|
||||
success = 1;
|
||||
@ -561,7 +563,7 @@ process_lock_agent(SocketEntry *e, int lock)
|
||||
lock_passwd = xstrdup(passwd);
|
||||
success = 1;
|
||||
}
|
||||
memset(passwd, 0, strlen(passwd));
|
||||
explicit_bzero(passwd, strlen(passwd));
|
||||
free(passwd);
|
||||
|
||||
buffer_put_int(&e->output, 1);
|
||||
|
10
ssh-dss.c
10
ssh-dss.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: ssh-dss.c,v 1.30 2014/01/09 23:20:00 djm Exp $ */
|
||||
/* $OpenBSD: ssh-dss.c,v 1.31 2014/02/02 03:44:31 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
*
|
||||
@ -65,7 +65,7 @@ ssh_dss_sign(const Key *key, u_char **sigp, u_int *lenp,
|
||||
}
|
||||
|
||||
sig = DSA_do_sign(digest, dlen, key->dsa);
|
||||
memset(digest, 'd', sizeof(digest));
|
||||
explicit_bzero(digest, sizeof(digest));
|
||||
|
||||
if (sig == NULL) {
|
||||
error("ssh_dss_sign: sign failed");
|
||||
@ -79,7 +79,7 @@ ssh_dss_sign(const Key *key, u_char **sigp, u_int *lenp,
|
||||
DSA_SIG_free(sig);
|
||||
return -1;
|
||||
}
|
||||
memset(sigblob, 0, SIGBLOB_LEN);
|
||||
explicit_bzero(sigblob, SIGBLOB_LEN);
|
||||
BN_bn2bin(sig->r, sigblob+ SIGBLOB_LEN - INTBLOB_LEN - rlen);
|
||||
BN_bn2bin(sig->s, sigblob+ SIGBLOB_LEN - slen);
|
||||
DSA_SIG_free(sig);
|
||||
@ -168,7 +168,7 @@ ssh_dss_verify(const Key *key, const u_char *signature, u_int signaturelen,
|
||||
fatal("%s: BN_bin2bn failed", __func__);
|
||||
|
||||
/* clean up */
|
||||
memset(sigblob, 0, len);
|
||||
explicit_bzero(sigblob, len);
|
||||
free(sigblob);
|
||||
|
||||
/* sha1 the data */
|
||||
@ -179,7 +179,7 @@ ssh_dss_verify(const Key *key, const u_char *signature, u_int signaturelen,
|
||||
}
|
||||
|
||||
ret = DSA_do_verify(digest, dlen, sig, key->dsa);
|
||||
memset(digest, 'd', sizeof(digest));
|
||||
explicit_bzero(digest, sizeof(digest));
|
||||
|
||||
DSA_SIG_free(sig);
|
||||
|
||||
|
11
ssh-ecdsa.c
11
ssh-ecdsa.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: ssh-ecdsa.c,v 1.8 2014/01/09 23:20:00 djm Exp $ */
|
||||
/* $OpenBSD: ssh-ecdsa.c,v 1.10 2014/02/03 23:28:00 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
* Copyright (c) 2010 Damien Miller. All rights reserved.
|
||||
@ -72,7 +72,7 @@ ssh_ecdsa_sign(const Key *key, u_char **sigp, u_int *lenp,
|
||||
}
|
||||
|
||||
sig = ECDSA_do_sign(digest, dlen, key->ecdsa);
|
||||
memset(digest, 'd', sizeof(digest));
|
||||
explicit_bzero(digest, sizeof(digest));
|
||||
|
||||
if (sig == NULL) {
|
||||
error("%s: sign failed", __func__);
|
||||
@ -140,9 +140,6 @@ ssh_ecdsa_verify(const Key *key, const u_char *signature, u_int signaturelen,
|
||||
/* parse signature */
|
||||
if ((sig = ECDSA_SIG_new()) == NULL)
|
||||
fatal("%s: ECDSA_SIG_new failed", __func__);
|
||||
if ((sig->r = BN_new()) == NULL ||
|
||||
(sig->s = BN_new()) == NULL)
|
||||
fatal("%s: BN_new failed", __func__);
|
||||
|
||||
buffer_init(&bb);
|
||||
buffer_append(&bb, sigblob, len);
|
||||
@ -153,7 +150,7 @@ ssh_ecdsa_verify(const Key *key, const u_char *signature, u_int signaturelen,
|
||||
buffer_free(&bb);
|
||||
|
||||
/* clean up */
|
||||
memset(sigblob, 0, len);
|
||||
explicit_bzero(sigblob, len);
|
||||
free(sigblob);
|
||||
|
||||
/* hash the data */
|
||||
@ -169,7 +166,7 @@ ssh_ecdsa_verify(const Key *key, const u_char *signature, u_int signaturelen,
|
||||
}
|
||||
|
||||
ret = ECDSA_do_verify(digest, dlen, sig, key->ecdsa);
|
||||
memset(digest, 'd', sizeof(digest));
|
||||
explicit_bzero(digest, sizeof(digest));
|
||||
|
||||
ECDSA_SIG_free(sig);
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: ssh-ed25519.c,v 1.1 2013/12/06 13:39:49 markus Exp $ */
|
||||
/* $OpenBSD: ssh-ed25519.c,v 1.3 2014/02/23 20:03:42 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2013 Markus Friedl <markus@openbsd.org>
|
||||
*
|
||||
@ -21,6 +21,7 @@
|
||||
|
||||
#include "crypto_api.h"
|
||||
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
@ -45,6 +46,11 @@ ssh_ed25519_sign(const Key *key, u_char **sigp, u_int *lenp,
|
||||
error("%s: no ED25519 key", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (datalen >= UINT_MAX - crypto_sign_ed25519_BYTES) {
|
||||
error("%s: datalen %u too long", __func__, datalen);
|
||||
return -1;
|
||||
}
|
||||
smlen = slen = datalen + crypto_sign_ed25519_BYTES;
|
||||
sig = xmalloc(slen);
|
||||
|
||||
@ -66,7 +72,7 @@ ssh_ed25519_sign(const Key *key, u_char **sigp, u_int *lenp,
|
||||
memcpy(*sigp, buffer_ptr(&b), len);
|
||||
}
|
||||
buffer_free(&b);
|
||||
memset(sig, 's', slen);
|
||||
explicit_bzero(sig, slen);
|
||||
free(sig);
|
||||
|
||||
return 0;
|
||||
@ -130,9 +136,9 @@ ssh_ed25519_verify(const Key *key, const u_char *signature, u_int signaturelen,
|
||||
}
|
||||
/* XXX compare 'm' and 'data' ? */
|
||||
|
||||
memset(sigblob, 's', len);
|
||||
memset(sm, 'S', smlen);
|
||||
memset(m, 'm', smlen); /* NB. mlen may be invalid if ret != 0 */
|
||||
explicit_bzero(sigblob, len);
|
||||
explicit_bzero(sm, smlen);
|
||||
explicit_bzero(m, smlen); /* NB. mlen may be invalid if ret != 0 */
|
||||
free(sigblob);
|
||||
free(sm);
|
||||
free(m);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: ssh-gss.h,v 1.10 2007/06/12 08:20:00 djm Exp $ */
|
||||
/* $OpenBSD: ssh-gss.h,v 1.11 2014/02/26 20:28:44 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
|
||||
*
|
||||
@ -104,6 +104,8 @@ void ssh_gssapi_set_oid_data(Gssctxt *, void *, size_t);
|
||||
void ssh_gssapi_set_oid(Gssctxt *, gss_OID);
|
||||
void ssh_gssapi_supported_oids(gss_OID_set *);
|
||||
ssh_gssapi_mech *ssh_gssapi_get_ctype(Gssctxt *);
|
||||
void ssh_gssapi_prepare_supported_oids(void);
|
||||
OM_uint32 ssh_gssapi_test_oid_supported(OM_uint32 *, gss_OID, int *);
|
||||
|
||||
OM_uint32 ssh_gssapi_import_name(Gssctxt *, const char *);
|
||||
OM_uint32 ssh_gssapi_init_ctx(Gssctxt *, int,
|
||||
|
@ -4,7 +4,7 @@ NAME
|
||||
ssh-keygen - authentication key generation, management and conversion
|
||||
|
||||
SYNOPSIS
|
||||
ssh-keygen [-q] [-b bits] -t type [-N new_passphrase] [-C comment]
|
||||
ssh-keygen [-q] [-b bits] [-t type] [-N new_passphrase] [-C comment]
|
||||
[-f output_keyfile]
|
||||
ssh-keygen -p [-P old_passphrase] [-N new_passphrase] [-f keyfile]
|
||||
ssh-keygen -i [-m key_format] [-f input_keyfile]
|
||||
@ -559,4 +559,4 @@ AUTHORS
|
||||
created OpenSSH. Markus Friedl contributed the support for SSH protocol
|
||||
versions 1.5 and 2.0.
|
||||
|
||||
OpenBSD 5.4 December 21, 2013 OpenBSD 5.4
|
||||
OpenBSD 5.5 February 5, 2014 OpenBSD 5.5
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" $OpenBSD: ssh-keygen.1,v 1.119 2013/12/21 07:10:47 tedu Exp $
|
||||
.\" $OpenBSD: ssh-keygen.1,v 1.120 2014/02/05 20:13:25 naddy Exp $
|
||||
.\"
|
||||
.\" Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
.\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@ -35,7 +35,7 @@
|
||||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd $Mdocdate: December 21 2013 $
|
||||
.Dd $Mdocdate: February 5 2014 $
|
||||
.Dt SSH-KEYGEN 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -46,7 +46,7 @@
|
||||
.Nm ssh-keygen
|
||||
.Op Fl q
|
||||
.Op Fl b Ar bits
|
||||
.Fl t Ar type
|
||||
.Op Fl t Ar type
|
||||
.Op Fl N Ar new_passphrase
|
||||
.Op Fl C Ar comment
|
||||
.Op Fl f Ar output_keyfile
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user