diff options
author | Colin Watson <cjwatson@debian.org> | 2014-03-20 00:24:29 +0000 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2014-03-20 00:24:29 +0000 |
commit | 796ba4fd011b5d0d9d78d592ba2f30fc9d5ed2e7 (patch) | |
tree | 98105bf1621565a2679d5f7f4d650561be2d7666 | |
parent | 9a975a9faed7c4f334e8c8490db3e77e102f2b21 (diff) | |
parent | 19158b2447e35838d69b2b735fb640d1e86061ea (diff) |
Import openssh_6.6p1.orig.tar.gz
-rw-r--r-- | ChangeLog | 222 | ||||
-rw-r--r-- | Makefile.in | 10 | ||||
-rw-r--r-- | README | 4 | ||||
-rw-r--r-- | auth-rsa.c | 22 | ||||
-rw-r--r-- | auth.h | 6 | ||||
-rw-r--r-- | auth1.c | 6 | ||||
-rw-r--r-- | auth2-chall.c | 6 | ||||
-rw-r--r-- | auth2-gss.c | 9 | ||||
-rw-r--r-- | auth2-jpake.c | 563 | ||||
-rw-r--r-- | auth2-passwd.c | 6 | ||||
-rw-r--r-- | auth2.c | 11 | ||||
-rw-r--r-- | authfd.c | 4 | ||||
-rw-r--r-- | authfile.c | 20 | ||||
-rw-r--r-- | bufaux.c | 8 | ||||
-rw-r--r-- | bufbn.c | 11 | ||||
-rw-r--r-- | bufec.c | 6 | ||||
-rw-r--r-- | buffer.c | 4 | ||||
-rw-r--r-- | canohost.c | 2 | ||||
-rw-r--r-- | channels.c | 15 | ||||
-rw-r--r-- | cipher-3des1.c | 6 | ||||
-rw-r--r-- | cipher-chachapoly.c | 10 | ||||
-rw-r--r-- | cipher.c | 22 | ||||
-rw-r--r-- | clientloop.c | 10 | ||||
-rw-r--r-- | config.h.in | 6 | ||||
-rwxr-xr-x | configure | 6 | ||||
-rw-r--r-- | configure.ac | 8 | ||||
-rw-r--r-- | contrib/caldera/openssh.spec | 4 | ||||
-rw-r--r-- | contrib/redhat/openssh.spec | 2 | ||||
-rw-r--r-- | contrib/suse/openssh.spec | 2 | ||||
-rw-r--r-- | digest-libc.c | 238 | ||||
-rw-r--r-- | digest-openssl.c (renamed from digest.c) | 25 | ||||
-rw-r--r-- | digest.h | 12 | ||||
-rw-r--r-- | gss-serv.c | 24 | ||||
-rw-r--r-- | hmac.c | 197 | ||||
-rw-r--r-- | hmac.h | 37 | ||||
-rw-r--r-- | hostfile.c | 33 | ||||
-rw-r--r-- | jpake.c | 456 | ||||
-rw-r--r-- | jpake.h | 114 | ||||
-rw-r--r-- | kex.c | 6 | ||||
-rw-r--r-- | kex.h | 7 | ||||
-rw-r--r-- | kexc25519.c | 4 | ||||
-rw-r--r-- | kexdhc.c | 4 | ||||
-rw-r--r-- | kexdhs.c | 4 | ||||
-rw-r--r-- | kexecdhc.c | 4 | ||||
-rw-r--r-- | kexecdhs.c | 4 | ||||
-rw-r--r-- | kexgexc.c | 4 | ||||
-rw-r--r-- | kexgexs.c | 4 | ||||
-rw-r--r-- | key.c | 12 | ||||
-rw-r--r-- | krl.c | 12 | ||||
-rw-r--r-- | mac.c | 94 | ||||
-rw-r--r-- | moduli.0 | 2 | ||||
-rw-r--r-- | monitor.c | 234 | ||||
-rw-r--r-- | monitor.h | 7 | ||||
-rw-r--r-- | monitor_wrap.c | 169 | ||||
-rw-r--r-- | monitor_wrap.h | 22 | ||||
-rw-r--r-- | openbsd-compat/Makefile.in | 4 | ||||
-rw-r--r-- | openbsd-compat/bsd-poll.c | 11 | ||||
-rw-r--r-- | openbsd-compat/explicit_bzero.c | 20 | ||||
-rw-r--r-- | openbsd-compat/openbsd-compat.h | 6 | ||||
-rw-r--r-- | openbsd-compat/openssl-compat.c | 10 | ||||
-rw-r--r-- | openbsd-compat/openssl-compat.h | 6 | ||||
-rw-r--r-- | packet.c | 16 | ||||
-rw-r--r-- | readconf.c | 72 | ||||
-rw-r--r-- | readconf.h | 5 | ||||
-rw-r--r-- | readpass.c | 8 | ||||
-rw-r--r-- | regress/Makefile | 3 | ||||
-rw-r--r-- | regress/agent-ptrace.sh | 2 | ||||
-rw-r--r-- | regress/agent.sh | 2 | ||||
-rw-r--r-- | regress/cert-hostkey.sh | 2 | ||||
-rw-r--r-- | regress/dhgex.sh | 54 | ||||
-rw-r--r-- | regress/host-expand.sh | 1 | ||||
-rw-r--r-- | regress/login-timeout.sh | 4 | ||||
-rw-r--r-- | regress/scp-ssh-wrapper.sh | 2 | ||||
-rw-r--r-- | regress/scp.sh | 2 | ||||
-rw-r--r-- | regress/setuid-allowed.c | 1 | ||||
-rw-r--r-- | regress/sftp-chroot.sh | 5 | ||||
-rw-r--r-- | rsa.c | 10 | ||||
-rw-r--r-- | sandbox-capsicum.c | 6 | ||||
-rw-r--r-- | sandbox-seccomp-filter.c | 3 | ||||
-rw-r--r-- | sandbox-systrace.c | 5 | ||||
-rw-r--r-- | schnorr.c | 668 | ||||
-rw-r--r-- | schnorr.h | 60 | ||||
-rw-r--r-- | scp.0 | 2 | ||||
-rw-r--r-- | servconf.c | 21 | ||||
-rw-r--r-- | servconf.h | 4 | ||||
-rw-r--r-- | serverloop.c | 4 | ||||
-rw-r--r-- | session.c | 13 | ||||
-rw-r--r-- | sftp-client.c | 4 | ||||
-rw-r--r-- | sftp-server.0 | 2 | ||||
-rw-r--r-- | sftp.0 | 2 | ||||
-rw-r--r-- | ssh-add.0 | 2 | ||||
-rw-r--r-- | ssh-add.c | 8 | ||||
-rw-r--r-- | ssh-agent.0 | 2 | ||||
-rw-r--r-- | ssh-agent.c | 20 | ||||
-rw-r--r-- | ssh-dss.c | 10 | ||||
-rw-r--r-- | ssh-ecdsa.c | 11 | ||||
-rw-r--r-- | ssh-ed25519.c | 16 | ||||
-rw-r--r-- | ssh-gss.h | 4 | ||||
-rw-r--r-- | ssh-keygen.0 | 4 | ||||
-rw-r--r-- | ssh-keygen.1 | 6 | ||||
-rw-r--r-- | ssh-keygen.c | 38 | ||||
-rw-r--r-- | ssh-keyscan.0 | 7 | ||||
-rw-r--r-- | ssh-keyscan.1 | 28 | ||||
-rw-r--r-- | ssh-keysign.0 | 2 | ||||
-rw-r--r-- | ssh-pkcs11-helper.0 | 2 | ||||
-rw-r--r-- | ssh-rsa.c | 14 | ||||
-rw-r--r-- | ssh.0 | 2 | ||||
-rw-r--r-- | ssh.c | 178 | ||||
-rw-r--r-- | ssh2.h | 8 | ||||
-rw-r--r-- | ssh_config.0 | 7 | ||||
-rw-r--r-- | ssh_config.5 | 10 | ||||
-rw-r--r-- | sshconnect.c | 35 | ||||
-rw-r--r-- | sshconnect1.c | 37 | ||||
-rw-r--r-- | sshconnect2.c | 311 | ||||
-rw-r--r-- | sshd.0 | 2 | ||||
-rw-r--r-- | sshd.c | 53 | ||||
-rw-r--r-- | sshd_config.0 | 12 | ||||
-rw-r--r-- | sshd_config.5 | 19 | ||||
-rw-r--r-- | sshlogin.c | 2 | ||||
-rw-r--r-- | version.h | 4 |
120 files changed, 1510 insertions, 3124 deletions
@@ -1,3 +1,224 @@ | |||
1 | 20140313 | ||
2 | - (djm) Release OpenSSH 6.6 | ||
3 | |||
4 | 20140304 | ||
5 | - OpenBSD CVS Sync | ||
6 | - djm@cvs.openbsd.org 2014/03/03 22:22:30 | ||
7 | [session.c] | ||
8 | ignore enviornment variables with embedded '=' or '\0' characters; | ||
9 | spotted by Jann Horn; ok deraadt@ | ||
10 | |||
11 | 20140301 | ||
12 | - (djm) [regress/Makefile] Disable dhgex regress test; it breaks when | ||
13 | no moduli file exists at the expected location. | ||
14 | |||
15 | 20140228 | ||
16 | - OpenBSD CVS Sync | ||
17 | - djm@cvs.openbsd.org 2014/02/27 00:41:49 | ||
18 | [bufbn.c] | ||
19 | fix unsigned overflow that could lead to reading a short ssh protocol | ||
20 | 1 bignum value; found by Ben Hawkes; ok deraadt@ | ||
21 | - djm@cvs.openbsd.org 2014/02/27 08:25:09 | ||
22 | [bufbn.c] | ||
23 | off by one in range check | ||
24 | - djm@cvs.openbsd.org 2014/02/27 22:47:07 | ||
25 | [sshd_config.5] | ||
26 | bz#2184 clarify behaviour of a keyword that appears in multiple | ||
27 | matching Match blocks; ok dtucker@ | ||
28 | - djm@cvs.openbsd.org 2014/02/27 22:57:40 | ||
29 | [version.h] | ||
30 | openssh-6.6 | ||
31 | - dtucker@cvs.openbsd.org 2014/01/19 23:43:02 | ||
32 | [regress/sftp-chroot.sh] | ||
33 | Don't use -q on sftp as it suppresses logging, instead redirect the | ||
34 | output to the regress logfile. | ||
35 | - dtucker@cvs.openbsd.org 2014/01/20 00:00:30 | ||
36 | [sregress/ftp-chroot.sh] | ||
37 | append to rather than truncating the log file | ||
38 | - dtucker@cvs.openbsd.org 2014/01/25 04:35:32 | ||
39 | [regress/Makefile regress/dhgex.sh] | ||
40 | Add a test for DH GEX sizes | ||
41 | - djm@cvs.openbsd.org 2014/01/26 10:22:10 | ||
42 | [regress/cert-hostkey.sh] | ||
43 | automatically generate revoked keys from listed keys rather than | ||
44 | manually specifying each type; from portable | ||
45 | (Id sync only) | ||
46 | - djm@cvs.openbsd.org 2014/01/26 10:49:17 | ||
47 | [scp-ssh-wrapper.sh scp.sh] | ||
48 | make sure $SCP is tested on the remote end rather than whichever one | ||
49 | happens to be in $PATH; from portable | ||
50 | (Id sync only) | ||
51 | - djm@cvs.openbsd.org 2014/02/27 20:04:16 | ||
52 | [login-timeout.sh] | ||
53 | remove any existing LoginGraceTime from sshd_config before adding | ||
54 | a specific one for the test back in | ||
55 | - djm@cvs.openbsd.org 2014/02/27 21:21:25 | ||
56 | [agent-ptrace.sh agent.sh] | ||
57 | keep return values that are printed in error messages; | ||
58 | from portable | ||
59 | (Id sync only) | ||
60 | - (djm) [README contrib/caldera/openssh.spec contrib/redhat/openssh.spec] | ||
61 | [contrib/suse/openssh.spec] Crank version numbers | ||
62 | - (djm) [regress/host-expand.sh] Add RCS Id | ||
63 | |||
64 | 20140227 | ||
65 | - OpenBSD CVS Sync | ||
66 | - djm@cvs.openbsd.org 2014/02/26 20:18:37 | ||
67 | [ssh.c] | ||
68 | bz#2205: avoid early hostname lookups unless canonicalisation is enabled; | ||
69 | ok dtucker@ markus@ | ||
70 | - djm@cvs.openbsd.org 2014/02/26 20:28:44 | ||
71 | [auth2-gss.c gss-serv.c ssh-gss.h sshd.c] | ||
72 | bz#2107 - cache OIDs of supported GSSAPI mechanisms before privsep | ||
73 | sandboxing, as running this code in the sandbox can cause violations; | ||
74 | ok markus@ | ||
75 | - djm@cvs.openbsd.org 2014/02/26 20:29:29 | ||
76 | [channels.c] | ||
77 | don't assume that the socks4 username is \0 terminated; | ||
78 | spotted by Ben Hawkes; ok markus@ | ||
79 | - markus@cvs.openbsd.org 2014/02/26 21:53:37 | ||
80 | [sshd.c] | ||
81 | ssh_gssapi_prepare_supported_oids needs GSSAPI | ||
82 | |||
83 | 20140224 | ||
84 | - OpenBSD CVS Sync | ||
85 | - djm@cvs.openbsd.org 2014/02/07 06:55:54 | ||
86 | [cipher.c mac.c] | ||
87 | remove some logging that makes ssh debugging output very verbose; | ||
88 | ok markus | ||
89 | - djm@cvs.openbsd.org 2014/02/15 23:05:36 | ||
90 | [channels.c] | ||
91 | avoid spurious "getsockname failed: Bad file descriptor" errors in ssh -W; | ||
92 | bz#2200, debian#738692 via Colin Watson; ok dtucker@ | ||
93 | - djm@cvs.openbsd.org 2014/02/22 01:32:19 | ||
94 | [readconf.c] | ||
95 | when processing Match blocks, skip 'exec' clauses if previous predicates | ||
96 | failed to match; ok markus@ | ||
97 | - djm@cvs.openbsd.org 2014/02/23 20:03:42 | ||
98 | [ssh-ed25519.c] | ||
99 | check for unsigned overflow; not reachable in OpenSSH but others might | ||
100 | copy our code... | ||
101 | - djm@cvs.openbsd.org 2014/02/23 20:11:36 | ||
102 | [readconf.c readconf.h ssh.c ssh_config.5] | ||
103 | reparse ssh_config and ~/.ssh/config if hostname canonicalisation changes | ||
104 | the hostname. This allows users to write configurations that always | ||
105 | refer to canonical hostnames, e.g. | ||
106 | |||
107 | CanonicalizeHostname yes | ||
108 | CanonicalDomains int.example.org example.org | ||
109 | CanonicalizeFallbackLocal no | ||
110 | |||
111 | Host *.int.example.org | ||
112 | Compression off | ||
113 | Host *.example.org | ||
114 | User djm | ||
115 | |||
116 | ok markus@ | ||
117 | |||
118 | 20140213 | ||
119 | - (dtucker) [configure.ac openbsd-compat/openssl-compat.{c,h}] Add compat | ||
120 | code for older OpenSSL versions that don't have EVP_MD_CTX_copy_ex. | ||
121 | |||
122 | 20140207 | ||
123 | - OpenBSD CVS Sync | ||
124 | - naddy@cvs.openbsd.org 2014/02/05 20:13:25 | ||
125 | [ssh-keygen.1 ssh-keygen.c] | ||
126 | tweak synopsis: calling ssh-keygen without any arguments is fine; ok jmc@ | ||
127 | while here, fix ordering in usage(); requested by jmc@ | ||
128 | - djm@cvs.openbsd.org 2014/02/06 22:21:01 | ||
129 | [sshconnect.c] | ||
130 | in ssh_create_socket(), only do the getaddrinfo for BindAddress when | ||
131 | BindAddress is actually specified. Fixes regression in 6.5 for | ||
132 | UsePrivilegedPort=yes; patch from Corinna Vinschen | ||
133 | |||
134 | 20140206 | ||
135 | - (dtucker) [openbsd-compat/bsd-poll.c] Don't bother checking for non-NULL | ||
136 | before freeing since free(NULL) is a no-op. ok djm. | ||
137 | - (djm) [sandbox-seccomp-filter.c] Not all Linux architectures define | ||
138 | __NR_shutdown; some go via the socketcall(2) multiplexer. | ||
139 | |||
140 | 20140205 | ||
141 | - (djm) [sandbox-capsicum.c] Don't fatal if Capsicum is offered by | ||
142 | headers/libc but not supported by the kernel. Patch from Loganaden | ||
143 | Velvindron @ AfriNIC | ||
144 | |||
145 | 20140204 | ||
146 | - OpenBSD CVS Sync | ||
147 | - markus@cvs.openbsd.org 2014/01/27 18:58:14 | ||
148 | [Makefile.in digest.c digest.h hostfile.c kex.h mac.c hmac.c hmac.h] | ||
149 | replace openssl HMAC with an implementation based on our ssh_digest_* | ||
150 | ok and feedback djm@ | ||
151 | - markus@cvs.openbsd.org 2014/01/27 19:18:54 | ||
152 | [auth-rsa.c cipher.c ssh-agent.c sshconnect1.c sshd.c] | ||
153 | replace openssl MD5 with our ssh_digest_*; ok djm@ | ||
154 | - markus@cvs.openbsd.org 2014/01/27 20:13:46 | ||
155 | [digest.c digest-openssl.c digest-libc.c Makefile.in] | ||
156 | rename digest.c to digest-openssl.c and add libc variant; ok djm@ | ||
157 | - jmc@cvs.openbsd.org 2014/01/28 14:13:39 | ||
158 | [ssh-keyscan.1] | ||
159 | kill some bad Pa; | ||
160 | From: Jan Stary | ||
161 | - djm@cvs.openbsd.org 2014/01/29 00:19:26 | ||
162 | [sshd.c] | ||
163 | use kill(0, ...) instead of killpg(0, ...); on most operating systems | ||
164 | they are equivalent, but SUSv2 describes the latter as having undefined | ||
165 | behaviour; from portable; ok dtucker | ||
166 | (Id sync only; change is already in portable) | ||
167 | - djm@cvs.openbsd.org 2014/01/29 06:18:35 | ||
168 | [Makefile.in auth.h auth2-jpake.c auth2.c jpake.c jpake.h monitor.c] | ||
169 | [monitor.h monitor_wrap.c monitor_wrap.h readconf.c readconf.h] | ||
170 | [schnorr.c schnorr.h servconf.c servconf.h ssh2.h sshconnect2.c] | ||
171 | remove experimental, never-enabled JPAKE code; ok markus@ | ||
172 | - jmc@cvs.openbsd.org 2014/01/29 14:04:51 | ||
173 | [sshd_config.5] | ||
174 | document kbdinteractiveauthentication; | ||
175 | requested From: Ross L Richardson | ||
176 | |||
177 | dtucker/markus helped explain its workings; | ||
178 | - djm@cvs.openbsd.org 2014/01/30 22:26:14 | ||
179 | [sandbox-systrace.c] | ||
180 | allow shutdown(2) syscall in sandbox - it may be called by packet_close() | ||
181 | from portable | ||
182 | (Id sync only; change is already in portable) | ||
183 | - tedu@cvs.openbsd.org 2014/01/31 16:39:19 | ||
184 | [auth2-chall.c authfd.c authfile.c bufaux.c bufec.c canohost.c] | ||
185 | [channels.c cipher-chachapoly.c clientloop.c configure.ac hostfile.c] | ||
186 | [kexc25519.c krl.c monitor.c sandbox-systrace.c session.c] | ||
187 | [sftp-client.c ssh-keygen.c ssh.c sshconnect2.c sshd.c sshlogin.c] | ||
188 | [openbsd-compat/explicit_bzero.c openbsd-compat/openbsd-compat.h] | ||
189 | replace most bzero with explicit_bzero, except a few that cna be memset | ||
190 | ok djm dtucker | ||
191 | - djm@cvs.openbsd.org 2014/02/02 03:44:32 | ||
192 | [auth1.c auth2-chall.c auth2-passwd.c authfile.c bufaux.c bufbn.c] | ||
193 | [buffer.c cipher-3des1.c cipher.c clientloop.c gss-serv.c kex.c] | ||
194 | [kexdhc.c kexdhs.c kexecdhc.c kexgexc.c kexecdhs.c kexgexs.c key.c] | ||
195 | [monitor.c monitor_wrap.c packet.c readpass.c rsa.c serverloop.c] | ||
196 | [ssh-add.c ssh-agent.c ssh-dss.c ssh-ecdsa.c ssh-ed25519.c] | ||
197 | [ssh-keygen.c ssh-rsa.c sshconnect.c sshconnect1.c sshconnect2.c] | ||
198 | [sshd.c] | ||
199 | convert memset of potentially-private data to explicit_bzero() | ||
200 | - djm@cvs.openbsd.org 2014/02/03 23:28:00 | ||
201 | [ssh-ecdsa.c] | ||
202 | fix memory leak; ECDSA_SIG_new() allocates 'r' and 's' for us, unlike | ||
203 | DSA_SIG_new. Reported by Batz Spear; ok markus@ | ||
204 | - djm@cvs.openbsd.org 2014/02/02 03:44:31 | ||
205 | [digest-libc.c digest-openssl.c] | ||
206 | convert memset of potentially-private data to explicit_bzero() | ||
207 | - djm@cvs.openbsd.org 2014/02/04 00:24:29 | ||
208 | [ssh.c] | ||
209 | delay lowercasing of hostname until right before hostname | ||
210 | canonicalisation to unbreak case-sensitive matching of ssh_config; | ||
211 | reported by Ike Devolder; ok markus@ | ||
212 | - (djm) [openbsd-compat/Makefile.in] Add missing explicit_bzero.o | ||
213 | - (djm) [regress/setuid-allowed.c] Missing string.h for strerror() | ||
214 | |||
215 | 20140131 | ||
216 | - (djm) [sandbox-seccomp-filter.c sandbox-systrace.c] Allow shutdown(2) | ||
217 | syscall from sandboxes; it may be called by packet_close. | ||
218 | - (dtucker) [readconf.c] Include <arpa/inet.h> for the hton macros. Fixes | ||
219 | build with HP-UX's compiler. Patch from Kevin Brott. | ||
220 | - (tim) [Makefile.in] build regress/setuid-allow. | ||
221 | |||
1 | 20140130 | 222 | 20140130 |
2 | - (djm) [configure.ac] Only check for width-specified integer types | 223 | - (djm) [configure.ac] Only check for width-specified integer types |
3 | in headers that actually exist. patch from Tom G. Christensen; | 224 | in headers that actually exist. patch from Tom G. Christensen; |
@@ -2663,3 +2884,4 @@ | |||
2663 | [contrib/suse/openssh.spec] Update for release 6.0 | 2884 | [contrib/suse/openssh.spec] Update for release 6.0 |
2664 | - (djm) [README] Update URL to release notes. | 2885 | - (djm) [README] Update URL to release notes. |
2665 | - (djm) Release openssh-6.0 | 2886 | - (djm) Release openssh-6.0 |
2887 | |||
diff --git a/Makefile.in b/Makefile.in index a8aa1272a..28a8ec41b 100644 --- a/Makefile.in +++ b/Makefile.in | |||
@@ -1,4 +1,4 @@ | |||
1 | # $Id: Makefile.in,v 1.352 2014/01/27 06:35:04 dtucker Exp $ | 1 | # $Id: Makefile.in,v 1.356 2014/02/04 00:12:56 djm Exp $ |
2 | 2 | ||
3 | # uncomment if you run a non bourne compatable shell. Ie. csh | 3 | # uncomment if you run a non bourne compatable shell. Ie. csh |
4 | #SHELL = @SH@ | 4 | #SHELL = @SH@ |
@@ -73,9 +73,9 @@ LIBSSH_OBJS=authfd.o authfile.o bufaux.o bufbn.o buffer.o \ | |||
73 | monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-rsa.o dh.o \ | 73 | monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-rsa.o dh.o \ |
74 | kexdh.o kexgex.o kexdhc.o kexgexc.o bufec.o kexecdh.o kexecdhc.o \ | 74 | kexdh.o kexgex.o kexdhc.o kexgexc.o bufec.o kexecdh.o kexecdhc.o \ |
75 | msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \ | 75 | msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \ |
76 | jpake.o schnorr.o ssh-pkcs11.o krl.o smult_curve25519_ref.o \ | 76 | ssh-pkcs11.o krl.o smult_curve25519_ref.o \ |
77 | kexc25519.o kexc25519c.o poly1305.o chacha.o cipher-chachapoly.o \ | 77 | kexc25519.o kexc25519c.o poly1305.o chacha.o cipher-chachapoly.o \ |
78 | ssh-ed25519.o digest.o \ | 78 | ssh-ed25519.o digest-openssl.o hmac.o \ |
79 | sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o blocks.o | 79 | sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o blocks.o |
80 | 80 | ||
81 | SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ | 81 | 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 \ | |||
88 | auth.o auth1.o auth2.o auth-options.o session.o \ | 88 | auth.o auth1.o auth2.o auth-options.o session.o \ |
89 | auth-chall.o auth2-chall.o groupaccess.o \ | 89 | auth-chall.o auth2-chall.o groupaccess.o \ |
90 | auth-skey.o auth-bsdauth.o auth2-hostbased.o auth2-kbdint.o \ | 90 | auth-skey.o auth-bsdauth.o auth2-hostbased.o auth2-kbdint.o \ |
91 | auth2-none.o auth2-passwd.o auth2-pubkey.o auth2-jpake.o \ | 91 | auth2-none.o auth2-passwd.o auth2-pubkey.o \ |
92 | monitor_mm.o monitor.o monitor_wrap.o kexdhs.o kexgexs.o kexecdhs.o \ | 92 | monitor_mm.o monitor.o monitor_wrap.o kexdhs.o kexgexs.o kexecdhs.o \ |
93 | kexc25519s.o auth-krb5.o \ | 93 | kexc25519s.o auth-krb5.o \ |
94 | auth2-gss.o gss-serv.o gss-serv-krb5.o \ | 94 | auth2-gss.o gss-serv.o gss-serv-krb5.o \ |
@@ -408,7 +408,7 @@ regress/setuid-allowed$(EXEEXT): $(srcdir)/regress/setuid-allowed.c | |||
408 | $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $? \ | 408 | $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $? \ |
409 | $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) | 409 | $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) |
410 | 410 | ||
411 | tests interop-tests: $(TARGETS) regress/modpipe$(EXEEXT) | 411 | tests interop-tests: $(TARGETS) regress/modpipe$(EXEEXT) regress/setuid-allowed$(EXEEXT) |
412 | BUILDDIR=`pwd`; \ | 412 | BUILDDIR=`pwd`; \ |
413 | TEST_SHELL="@TEST_SHELL@"; \ | 413 | TEST_SHELL="@TEST_SHELL@"; \ |
414 | TEST_SSH_SCP="$${BUILDDIR}/scp"; \ | 414 | TEST_SSH_SCP="$${BUILDDIR}/scp"; \ |
@@ -1,4 +1,4 @@ | |||
1 | See http://www.openssh.com/txt/release-6.5 for the release notes. | 1 | See http://www.openssh.com/txt/release-6.6 for the release notes. |
2 | 2 | ||
3 | - A Japanese translation of this document and of the OpenSSH FAQ is | 3 | - A Japanese translation of this document and of the OpenSSH FAQ is |
4 | - available at http://www.unixuser.org/~haruyama/security/openssh/index.html | 4 | - available at http://www.unixuser.org/~haruyama/security/openssh/index.html |
@@ -62,4 +62,4 @@ References - | |||
62 | [6] http://www.openbsd.org/cgi-bin/man.cgi?query=style&sektion=9 | 62 | [6] http://www.openbsd.org/cgi-bin/man.cgi?query=style&sektion=9 |
63 | [7] http://www.openssh.com/faq.html | 63 | [7] http://www.openssh.com/faq.html |
64 | 64 | ||
65 | $Id: README,v 1.85 2014/01/16 07:51:45 djm Exp $ | 65 | $Id: README,v 1.86 2014/02/27 23:03:53 djm Exp $ |
diff --git a/auth-rsa.c b/auth-rsa.c index 545aa496a..5dad6c3dc 100644 --- a/auth-rsa.c +++ b/auth-rsa.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: auth-rsa.c,v 1.85 2013/07/12 00:19:58 djm Exp $ */ | 1 | /* $OpenBSD: auth-rsa.c,v 1.86 2014/01/27 19:18:54 markus Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -20,7 +20,6 @@ | |||
20 | #include <sys/stat.h> | 20 | #include <sys/stat.h> |
21 | 21 | ||
22 | #include <openssl/rsa.h> | 22 | #include <openssl/rsa.h> |
23 | #include <openssl/md5.h> | ||
24 | 23 | ||
25 | #include <pwd.h> | 24 | #include <pwd.h> |
26 | #include <stdio.h> | 25 | #include <stdio.h> |
@@ -48,6 +47,8 @@ | |||
48 | #include "ssh.h" | 47 | #include "ssh.h" |
49 | #include "misc.h" | 48 | #include "misc.h" |
50 | 49 | ||
50 | #include "digest.h" | ||
51 | |||
51 | /* import */ | 52 | /* import */ |
52 | extern ServerOptions options; | 53 | extern ServerOptions options; |
53 | 54 | ||
@@ -91,12 +92,13 @@ int | |||
91 | auth_rsa_verify_response(Key *key, BIGNUM *challenge, u_char response[16]) | 92 | auth_rsa_verify_response(Key *key, BIGNUM *challenge, u_char response[16]) |
92 | { | 93 | { |
93 | u_char buf[32], mdbuf[16]; | 94 | u_char buf[32], mdbuf[16]; |
94 | MD5_CTX md; | 95 | struct ssh_digest_ctx *md; |
95 | int len; | 96 | int len; |
96 | 97 | ||
97 | /* don't allow short keys */ | 98 | /* don't allow short keys */ |
98 | if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) { | 99 | if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) { |
99 | error("auth_rsa_verify_response: RSA modulus too small: %d < minimum %d bits", | 100 | error("%s: RSA modulus too small: %d < minimum %d bits", |
101 | __func__, | ||
100 | BN_num_bits(key->rsa->n), SSH_RSA_MINIMUM_MODULUS_SIZE); | 102 | BN_num_bits(key->rsa->n), SSH_RSA_MINIMUM_MODULUS_SIZE); |
101 | return (0); | 103 | return (0); |
102 | } | 104 | } |
@@ -104,13 +106,15 @@ auth_rsa_verify_response(Key *key, BIGNUM *challenge, u_char response[16]) | |||
104 | /* The response is MD5 of decrypted challenge plus session id. */ | 106 | /* The response is MD5 of decrypted challenge plus session id. */ |
105 | len = BN_num_bytes(challenge); | 107 | len = BN_num_bytes(challenge); |
106 | if (len <= 0 || len > 32) | 108 | if (len <= 0 || len > 32) |
107 | fatal("auth_rsa_verify_response: bad challenge length %d", len); | 109 | fatal("%s: bad challenge length %d", __func__, len); |
108 | memset(buf, 0, 32); | 110 | memset(buf, 0, 32); |
109 | BN_bn2bin(challenge, buf + 32 - len); | 111 | BN_bn2bin(challenge, buf + 32 - len); |
110 | MD5_Init(&md); | 112 | if ((md = ssh_digest_start(SSH_DIGEST_MD5)) == NULL || |
111 | MD5_Update(&md, buf, 32); | 113 | ssh_digest_update(md, buf, 32) < 0 || |
112 | MD5_Update(&md, session_id, 16); | 114 | ssh_digest_update(md, session_id, 16) < 0 || |
113 | MD5_Final(mdbuf, &md); | 115 | ssh_digest_final(md, mdbuf, sizeof(mdbuf)) < 0) |
116 | fatal("%s: md5 failed", __func__); | ||
117 | ssh_digest_free(md); | ||
114 | 118 | ||
115 | /* Verify that the response is the original challenge. */ | 119 | /* Verify that the response is the original challenge. */ |
116 | if (timingsafe_bcmp(response, mdbuf, 16) != 0) { | 120 | if (timingsafe_bcmp(response, mdbuf, 16) != 0) { |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: auth.h,v 1.76 2013/07/19 07:37:48 markus Exp $ */ | 1 | /* $OpenBSD: auth.h,v 1.77 2014/01/29 06:18:35 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 4 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
@@ -61,7 +61,6 @@ struct Authctxt { | |||
61 | char *style; | 61 | char *style; |
62 | void *kbdintctxt; | 62 | void *kbdintctxt; |
63 | char *info; /* Extra info for next auth_log */ | 63 | char *info; /* Extra info for next auth_log */ |
64 | void *jpake_ctx; | ||
65 | #ifdef BSD_AUTH | 64 | #ifdef BSD_AUTH |
66 | auth_session_t *as; | 65 | auth_session_t *as; |
67 | #endif | 66 | #endif |
@@ -175,9 +174,6 @@ int bsdauth_respond(void *, u_int, char **); | |||
175 | int skey_query(void *, char **, char **, u_int *, char ***, u_int **); | 174 | int skey_query(void *, char **, char **, u_int *, char ***, u_int **); |
176 | int skey_respond(void *, u_int, char **); | 175 | int skey_respond(void *, u_int, char **); |
177 | 176 | ||
178 | void auth2_jpake_get_pwdata(Authctxt *, BIGNUM **, char **, char **); | ||
179 | void auth2_jpake_stop(Authctxt *); | ||
180 | |||
181 | int allowed_user(struct passwd *); | 177 | int allowed_user(struct passwd *); |
182 | struct passwd * getpwnamallow(const char *user); | 178 | struct passwd * getpwnamallow(const char *user); |
183 | 179 | ||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: auth1.c,v 1.79 2013/05/19 02:42:42 djm Exp $ */ | 1 | /* $OpenBSD: auth1.c,v 1.80 2014/02/02 03:44:31 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 3 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
4 | * All rights reserved | 4 | * All rights reserved |
@@ -129,7 +129,7 @@ auth1_process_password(Authctxt *authctxt) | |||
129 | /* Try authentication with the password. */ | 129 | /* Try authentication with the password. */ |
130 | authenticated = PRIVSEP(auth_password(authctxt, password)); | 130 | authenticated = PRIVSEP(auth_password(authctxt, password)); |
131 | 131 | ||
132 | memset(password, 0, dlen); | 132 | explicit_bzero(password, dlen); |
133 | free(password); | 133 | free(password); |
134 | 134 | ||
135 | return (authenticated); | 135 | return (authenticated); |
@@ -222,7 +222,7 @@ auth1_process_tis_response(Authctxt *authctxt) | |||
222 | response = packet_get_string(&dlen); | 222 | response = packet_get_string(&dlen); |
223 | packet_check_eom(); | 223 | packet_check_eom(); |
224 | authenticated = verify_response(authctxt, response); | 224 | authenticated = verify_response(authctxt, response); |
225 | memset(response, 'r', dlen); | 225 | explicit_bzero(response, dlen); |
226 | free(response); | 226 | free(response); |
227 | 227 | ||
228 | return (authenticated); | 228 | return (authenticated); |
diff --git a/auth2-chall.c b/auth2-chall.c index 031c2828c..980250a91 100644 --- a/auth2-chall.c +++ b/auth2-chall.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: auth2-chall.c,v 1.39 2013/11/08 00:39:14 djm Exp $ */ | 1 | /* $OpenBSD: auth2-chall.c,v 1.41 2014/02/02 03:44:31 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2001 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2001 Markus Friedl. All rights reserved. |
4 | * Copyright (c) 2001 Per Allansson. All rights reserved. | 4 | * Copyright (c) 2001 Per Allansson. All rights reserved. |
@@ -148,7 +148,7 @@ kbdint_free(KbdintAuthctxt *kbdintctxt) | |||
148 | if (kbdintctxt->device) | 148 | if (kbdintctxt->device) |
149 | kbdint_reset_device(kbdintctxt); | 149 | kbdint_reset_device(kbdintctxt); |
150 | free(kbdintctxt->devices); | 150 | free(kbdintctxt->devices); |
151 | bzero(kbdintctxt, sizeof(*kbdintctxt)); | 151 | explicit_bzero(kbdintctxt, sizeof(*kbdintctxt)); |
152 | free(kbdintctxt); | 152 | free(kbdintctxt); |
153 | } | 153 | } |
154 | /* get next device */ | 154 | /* get next device */ |
@@ -312,7 +312,7 @@ input_userauth_info_response(int type, u_int32_t seq, void *ctxt) | |||
312 | res = kbdintctxt->device->respond(kbdintctxt->ctxt, nresp, response); | 312 | res = kbdintctxt->device->respond(kbdintctxt->ctxt, nresp, response); |
313 | 313 | ||
314 | for (i = 0; i < nresp; i++) { | 314 | for (i = 0; i < nresp; i++) { |
315 | memset(response[i], 'r', strlen(response[i])); | 315 | explicit_bzero(response[i], strlen(response[i])); |
316 | free(response[i]); | 316 | free(response[i]); |
317 | } | 317 | } |
318 | free(response); | 318 | free(response); |
diff --git a/auth2-gss.c b/auth2-gss.c index 638d8f88e..c28a705cb 100644 --- a/auth2-gss.c +++ b/auth2-gss.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: auth2-gss.c,v 1.20 2013/05/17 00:13:13 djm Exp $ */ | 1 | /* $OpenBSD: auth2-gss.c,v 1.21 2014/02/26 20:28:44 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. | 4 | * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. |
@@ -62,7 +62,6 @@ userauth_gssapi(Authctxt *authctxt) | |||
62 | gss_OID_desc goid = {0, NULL}; | 62 | gss_OID_desc goid = {0, NULL}; |
63 | Gssctxt *ctxt = NULL; | 63 | Gssctxt *ctxt = NULL; |
64 | int mechs; | 64 | int mechs; |
65 | gss_OID_set supported; | ||
66 | int present; | 65 | int present; |
67 | OM_uint32 ms; | 66 | OM_uint32 ms; |
68 | u_int len; | 67 | u_int len; |
@@ -77,7 +76,6 @@ userauth_gssapi(Authctxt *authctxt) | |||
77 | return (0); | 76 | return (0); |
78 | } | 77 | } |
79 | 78 | ||
80 | ssh_gssapi_supported_oids(&supported); | ||
81 | do { | 79 | do { |
82 | mechs--; | 80 | mechs--; |
83 | 81 | ||
@@ -90,15 +88,12 @@ userauth_gssapi(Authctxt *authctxt) | |||
90 | doid[1] == len - 2) { | 88 | doid[1] == len - 2) { |
91 | goid.elements = doid + 2; | 89 | goid.elements = doid + 2; |
92 | goid.length = len - 2; | 90 | goid.length = len - 2; |
93 | gss_test_oid_set_member(&ms, &goid, supported, | 91 | ssh_gssapi_test_oid_supported(&ms, &goid, &present); |
94 | &present); | ||
95 | } else { | 92 | } else { |
96 | logit("Badly formed OID received"); | 93 | logit("Badly formed OID received"); |
97 | } | 94 | } |
98 | } while (mechs > 0 && !present); | 95 | } while (mechs > 0 && !present); |
99 | 96 | ||
100 | gss_release_oid_set(&ms, &supported); | ||
101 | |||
102 | if (!present) { | 97 | if (!present) { |
103 | free(doid); | 98 | free(doid); |
104 | authctxt->server_caused_failure = 1; | 99 | authctxt->server_caused_failure = 1; |
diff --git a/auth2-jpake.c b/auth2-jpake.c deleted file mode 100644 index 78a6b8817..000000000 --- a/auth2-jpake.c +++ /dev/null | |||
@@ -1,563 +0,0 @@ | |||
1 | /* $OpenBSD: auth2-jpake.c,v 1.6 2013/05/17 00:13:13 djm Exp $ */ | ||
2 | /* | ||
3 | * Copyright (c) 2008 Damien Miller. All rights reserved. | ||
4 | * | ||
5 | * Permission to use, copy, modify, and distribute this software for any | ||
6 | * purpose with or without fee is hereby granted, provided that the above | ||
7 | * copyright notice and this permission notice appear in all copies. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
10 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
11 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
12 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
13 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
16 | */ | ||
17 | |||
18 | /* | ||
19 | * Server side of zero-knowledge password auth using J-PAKE protocol | ||
20 | * as described in: | ||
21 | * | ||
22 | * F. Hao, P. Ryan, "Password Authenticated Key Exchange by Juggling", | ||
23 | * 16th Workshop on Security Protocols, Cambridge, April 2008 | ||
24 | * | ||
25 | * http://grouper.ieee.org/groups/1363/Research/contributions/hao-ryan-2008.pdf | ||
26 | */ | ||
27 | |||
28 | #ifdef JPAKE | ||
29 | |||
30 | #include <sys/types.h> | ||
31 | #include <sys/param.h> | ||
32 | |||
33 | #include <pwd.h> | ||
34 | #include <stdio.h> | ||
35 | #include <string.h> | ||
36 | #include <login_cap.h> | ||
37 | |||
38 | #include <openssl/bn.h> | ||
39 | #include <openssl/evp.h> | ||
40 | |||
41 | #include "xmalloc.h" | ||
42 | #include "ssh2.h" | ||
43 | #include "key.h" | ||
44 | #include "hostfile.h" | ||
45 | #include "auth.h" | ||
46 | #include "buffer.h" | ||
47 | #include "packet.h" | ||
48 | #include "dispatch.h" | ||
49 | #include "log.h" | ||
50 | #include "servconf.h" | ||
51 | #include "auth-options.h" | ||
52 | #include "canohost.h" | ||
53 | #ifdef GSSAPI | ||
54 | #include "ssh-gss.h" | ||
55 | #endif | ||
56 | #include "monitor_wrap.h" | ||
57 | |||
58 | #include "schnorr.h" | ||
59 | #include "jpake.h" | ||
60 | |||
61 | /* | ||
62 | * XXX options->permit_empty_passwd (at the moment, they will be refused | ||
63 | * anyway because they will mismatch on fake salt. | ||
64 | */ | ||
65 | |||
66 | /* Dispatch handlers */ | ||
67 | static void input_userauth_jpake_client_step1(int, u_int32_t, void *); | ||
68 | static void input_userauth_jpake_client_step2(int, u_int32_t, void *); | ||
69 | static void input_userauth_jpake_client_confirm(int, u_int32_t, void *); | ||
70 | |||
71 | static int auth2_jpake_start(Authctxt *); | ||
72 | |||
73 | /* import */ | ||
74 | extern ServerOptions options; | ||
75 | extern u_char *session_id2; | ||
76 | extern u_int session_id2_len; | ||
77 | |||
78 | /* | ||
79 | * Attempt J-PAKE authentication. | ||
80 | */ | ||
81 | static int | ||
82 | userauth_jpake(Authctxt *authctxt) | ||
83 | { | ||
84 | int authenticated = 0; | ||
85 | |||
86 | packet_check_eom(); | ||
87 | |||
88 | debug("jpake-01@openssh.com requested"); | ||
89 | |||
90 | if (authctxt->user != NULL) { | ||
91 | if (authctxt->jpake_ctx == NULL) | ||
92 | authctxt->jpake_ctx = jpake_new(); | ||
93 | if (options.zero_knowledge_password_authentication) | ||
94 | authenticated = auth2_jpake_start(authctxt); | ||
95 | } | ||
96 | |||
97 | return authenticated; | ||
98 | } | ||
99 | |||
100 | Authmethod method_jpake = { | ||
101 | "jpake-01@openssh.com", | ||
102 | userauth_jpake, | ||
103 | &options.zero_knowledge_password_authentication | ||
104 | }; | ||
105 | |||
106 | /* Clear context and callbacks */ | ||
107 | void | ||
108 | auth2_jpake_stop(Authctxt *authctxt) | ||
109 | { | ||
110 | /* unregister callbacks */ | ||
111 | dispatch_set(SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP1, NULL); | ||
112 | dispatch_set(SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP2, NULL); | ||
113 | dispatch_set(SSH2_MSG_USERAUTH_JPAKE_CLIENT_CONFIRM, NULL); | ||
114 | if (authctxt->jpake_ctx != NULL) { | ||
115 | jpake_free(authctxt->jpake_ctx); | ||
116 | authctxt->jpake_ctx = NULL; | ||
117 | } | ||
118 | } | ||
119 | |||
120 | /* Returns 1 if 'c' is a valid crypt(3) salt character, 0 otherwise */ | ||
121 | static int | ||
122 | valid_crypt_salt(int c) | ||
123 | { | ||
124 | if (c >= 'A' && c <= 'Z') | ||
125 | return 1; | ||
126 | if (c >= 'a' && c <= 'z') | ||
127 | return 1; | ||
128 | if (c >= '.' && c <= '9') | ||
129 | return 1; | ||
130 | return 0; | ||
131 | } | ||
132 | |||
133 | /* | ||
134 | * Derive fake salt as H(username || first_private_host_key) | ||
135 | * This provides relatively stable fake salts for non-existent | ||
136 | * users and avoids the jpake method becoming an account validity | ||
137 | * oracle. | ||
138 | */ | ||
139 | static void | ||
140 | derive_rawsalt(const char *username, u_char *rawsalt, u_int len) | ||
141 | { | ||
142 | u_char *digest; | ||
143 | u_int digest_len; | ||
144 | Buffer b; | ||
145 | Key *k; | ||
146 | |||
147 | buffer_init(&b); | ||
148 | buffer_put_cstring(&b, username); | ||
149 | if ((k = get_hostkey_by_index(0)) == NULL || | ||
150 | (k->flags & KEY_FLAG_EXT)) | ||
151 | fatal("%s: no hostkeys", __func__); | ||
152 | switch (k->type) { | ||
153 | case KEY_RSA1: | ||
154 | case KEY_RSA: | ||
155 | if (k->rsa->p == NULL || k->rsa->q == NULL) | ||
156 | fatal("%s: RSA key missing p and/or q", __func__); | ||
157 | buffer_put_bignum2(&b, k->rsa->p); | ||
158 | buffer_put_bignum2(&b, k->rsa->q); | ||
159 | break; | ||
160 | case KEY_DSA: | ||
161 | if (k->dsa->priv_key == NULL) | ||
162 | fatal("%s: DSA key missing priv_key", __func__); | ||
163 | buffer_put_bignum2(&b, k->dsa->priv_key); | ||
164 | break; | ||
165 | case KEY_ECDSA: | ||
166 | if (EC_KEY_get0_private_key(k->ecdsa) == NULL) | ||
167 | fatal("%s: ECDSA key missing priv_key", __func__); | ||
168 | buffer_put_bignum2(&b, EC_KEY_get0_private_key(k->ecdsa)); | ||
169 | break; | ||
170 | default: | ||
171 | fatal("%s: unknown key type %d", __func__, k->type); | ||
172 | } | ||
173 | if (hash_buffer(buffer_ptr(&b), buffer_len(&b), EVP_sha256(), | ||
174 | &digest, &digest_len) != 0) | ||
175 | fatal("%s: hash_buffer", __func__); | ||
176 | buffer_free(&b); | ||
177 | if (len > digest_len) | ||
178 | fatal("%s: not enough bytes for rawsalt (want %u have %u)", | ||
179 | __func__, len, digest_len); | ||
180 | memcpy(rawsalt, digest, len); | ||
181 | bzero(digest, digest_len); | ||
182 | free(digest); | ||
183 | } | ||
184 | |||
185 | /* ASCII an integer [0, 64) for inclusion in a password/salt */ | ||
186 | static char | ||
187 | pw_encode64(u_int i64) | ||
188 | { | ||
189 | const u_char e64[] = | ||
190 | "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; | ||
191 | return e64[i64 % 64]; | ||
192 | } | ||
193 | |||
194 | /* Generate ASCII salt bytes for user */ | ||
195 | static char * | ||
196 | makesalt(u_int want, const char *user) | ||
197 | { | ||
198 | u_char rawsalt[32]; | ||
199 | static char ret[33]; | ||
200 | u_int i; | ||
201 | |||
202 | if (want > sizeof(ret) - 1) | ||
203 | fatal("%s: want %u", __func__, want); | ||
204 | |||
205 | derive_rawsalt(user, rawsalt, sizeof(rawsalt)); | ||
206 | bzero(ret, sizeof(ret)); | ||
207 | for (i = 0; i < want; i++) | ||
208 | ret[i] = pw_encode64(rawsalt[i]); | ||
209 | bzero(rawsalt, sizeof(rawsalt)); | ||
210 | |||
211 | return ret; | ||
212 | } | ||
213 | |||
214 | /* | ||
215 | * Select the system's default password hashing scheme and generate | ||
216 | * a stable fake salt under it for use by a non-existent account. | ||
217 | * Prevents jpake method being used to infer the validity of accounts. | ||
218 | */ | ||
219 | static void | ||
220 | fake_salt_and_scheme(Authctxt *authctxt, char **salt, char **scheme) | ||
221 | { | ||
222 | char *rounds_s, *style; | ||
223 | long long rounds; | ||
224 | login_cap_t *lc; | ||
225 | |||
226 | |||
227 | if ((lc = login_getclass(authctxt->pw->pw_class)) == NULL && | ||
228 | (lc = login_getclass(NULL)) == NULL) | ||
229 | fatal("%s: login_getclass failed", __func__); | ||
230 | style = login_getcapstr(lc, "localcipher", NULL, NULL); | ||
231 | if (style == NULL) | ||
232 | style = xstrdup("blowfish,6"); | ||
233 | login_close(lc); | ||
234 | |||
235 | if ((rounds_s = strchr(style, ',')) != NULL) | ||
236 | *rounds_s++ = '\0'; | ||
237 | rounds = strtonum(rounds_s, 1, 1<<31, NULL); | ||
238 | |||
239 | if (strcmp(style, "md5") == 0) { | ||
240 | xasprintf(salt, "$1$%s$", makesalt(8, authctxt->user)); | ||
241 | *scheme = xstrdup("md5"); | ||
242 | } else if (strcmp(style, "old") == 0) { | ||
243 | *salt = xstrdup(makesalt(2, authctxt->user)); | ||
244 | *scheme = xstrdup("crypt"); | ||
245 | } else if (strcmp(style, "newsalt") == 0) { | ||
246 | rounds = MAX(rounds, 7250); | ||
247 | rounds = MIN(rounds, (1<<24) - 1); | ||
248 | xasprintf(salt, "_%c%c%c%c%s", | ||
249 | pw_encode64(rounds), pw_encode64(rounds >> 6), | ||
250 | pw_encode64(rounds >> 12), pw_encode64(rounds >> 18), | ||
251 | makesalt(4, authctxt->user)); | ||
252 | *scheme = xstrdup("crypt-extended"); | ||
253 | } else { | ||
254 | /* Default to blowfish */ | ||
255 | rounds = MAX(rounds, 3); | ||
256 | rounds = MIN(rounds, 31); | ||
257 | xasprintf(salt, "$2a$%02lld$%s", rounds, | ||
258 | makesalt(22, authctxt->user)); | ||
259 | *scheme = xstrdup("bcrypt"); | ||
260 | } | ||
261 | free(style); | ||
262 | debug3("%s: fake %s salt for user %s: %s", | ||
263 | __func__, *scheme, authctxt->user, *salt); | ||
264 | } | ||
265 | |||
266 | /* | ||
267 | * Fetch password hashing scheme, password salt and derive shared secret | ||
268 | * for user. If user does not exist, a fake but stable and user-unique | ||
269 | * salt will be returned. | ||
270 | */ | ||
271 | void | ||
272 | auth2_jpake_get_pwdata(Authctxt *authctxt, BIGNUM **s, | ||
273 | char **hash_scheme, char **salt) | ||
274 | { | ||
275 | char *cp; | ||
276 | u_char *secret; | ||
277 | u_int secret_len, salt_len; | ||
278 | |||
279 | #ifdef JPAKE_DEBUG | ||
280 | debug3("%s: valid %d pw %.5s...", __func__, | ||
281 | authctxt->valid, authctxt->pw->pw_passwd); | ||
282 | #endif | ||
283 | |||
284 | *salt = NULL; | ||
285 | *hash_scheme = NULL; | ||
286 | if (authctxt->valid) { | ||
287 | if (strncmp(authctxt->pw->pw_passwd, "$2$", 3) == 0 && | ||
288 | strlen(authctxt->pw->pw_passwd) > 28) { | ||
289 | /* | ||
290 | * old-variant bcrypt: | ||
291 | * "$2$", 2 digit rounds, "$", 22 bytes salt | ||
292 | */ | ||
293 | salt_len = 3 + 2 + 1 + 22 + 1; | ||
294 | *salt = xmalloc(salt_len); | ||
295 | strlcpy(*salt, authctxt->pw->pw_passwd, salt_len); | ||
296 | *hash_scheme = xstrdup("bcrypt"); | ||
297 | } else if (strncmp(authctxt->pw->pw_passwd, "$2a$", 4) == 0 && | ||
298 | strlen(authctxt->pw->pw_passwd) > 29) { | ||
299 | /* | ||
300 | * current-variant bcrypt: | ||
301 | * "$2a$", 2 digit rounds, "$", 22 bytes salt | ||
302 | */ | ||
303 | salt_len = 4 + 2 + 1 + 22 + 1; | ||
304 | *salt = xmalloc(salt_len); | ||
305 | strlcpy(*salt, authctxt->pw->pw_passwd, salt_len); | ||
306 | *hash_scheme = xstrdup("bcrypt"); | ||
307 | } else if (strncmp(authctxt->pw->pw_passwd, "$1$", 3) == 0 && | ||
308 | strlen(authctxt->pw->pw_passwd) > 5) { | ||
309 | /* | ||
310 | * md5crypt: | ||
311 | * "$1$", salt until "$" | ||
312 | */ | ||
313 | cp = strchr(authctxt->pw->pw_passwd + 3, '$'); | ||
314 | if (cp != NULL) { | ||
315 | salt_len = (cp - authctxt->pw->pw_passwd) + 1; | ||
316 | *salt = xmalloc(salt_len); | ||
317 | strlcpy(*salt, authctxt->pw->pw_passwd, | ||
318 | salt_len); | ||
319 | *hash_scheme = xstrdup("md5crypt"); | ||
320 | } | ||
321 | } else if (strncmp(authctxt->pw->pw_passwd, "_", 1) == 0 && | ||
322 | strlen(authctxt->pw->pw_passwd) > 9) { | ||
323 | /* | ||
324 | * BSDI extended crypt: | ||
325 | * "_", 4 digits count, 4 chars salt | ||
326 | */ | ||
327 | salt_len = 1 + 4 + 4 + 1; | ||
328 | *salt = xmalloc(salt_len); | ||
329 | strlcpy(*salt, authctxt->pw->pw_passwd, salt_len); | ||
330 | *hash_scheme = xstrdup("crypt-extended"); | ||
331 | } else if (strlen(authctxt->pw->pw_passwd) == 13 && | ||
332 | valid_crypt_salt(authctxt->pw->pw_passwd[0]) && | ||
333 | valid_crypt_salt(authctxt->pw->pw_passwd[1])) { | ||
334 | /* | ||
335 | * traditional crypt: | ||
336 | * 2 chars salt | ||
337 | */ | ||
338 | salt_len = 2 + 1; | ||
339 | *salt = xmalloc(salt_len); | ||
340 | strlcpy(*salt, authctxt->pw->pw_passwd, salt_len); | ||
341 | *hash_scheme = xstrdup("crypt"); | ||
342 | } | ||
343 | if (*salt == NULL) { | ||
344 | debug("%s: unrecognised crypt scheme for user %s", | ||
345 | __func__, authctxt->pw->pw_name); | ||
346 | } | ||
347 | } | ||
348 | if (*salt == NULL) | ||
349 | fake_salt_and_scheme(authctxt, salt, hash_scheme); | ||
350 | |||
351 | if (hash_buffer(authctxt->pw->pw_passwd, | ||
352 | strlen(authctxt->pw->pw_passwd), EVP_sha256(), | ||
353 | &secret, &secret_len) != 0) | ||
354 | fatal("%s: hash_buffer", __func__); | ||
355 | if ((*s = BN_bin2bn(secret, secret_len, NULL)) == NULL) | ||
356 | fatal("%s: BN_bin2bn (secret)", __func__); | ||
357 | #ifdef JPAKE_DEBUG | ||
358 | debug3("%s: salt = %s (len %u)", __func__, | ||
359 | *salt, (u_int)strlen(*salt)); | ||
360 | debug3("%s: scheme = %s", __func__, *hash_scheme); | ||
361 | JPAKE_DEBUG_BN((*s, "%s: s = ", __func__)); | ||
362 | #endif | ||
363 | bzero(secret, secret_len); | ||
364 | free(secret); | ||
365 | } | ||
366 | |||
367 | /* | ||
368 | * Begin authentication attempt. | ||
369 | * Note, sets authctxt->postponed while in subprotocol | ||
370 | */ | ||
371 | static int | ||
372 | auth2_jpake_start(Authctxt *authctxt) | ||
373 | { | ||
374 | struct jpake_ctx *pctx = authctxt->jpake_ctx; | ||
375 | u_char *x3_proof, *x4_proof; | ||
376 | u_int x3_proof_len, x4_proof_len; | ||
377 | char *salt, *hash_scheme; | ||
378 | |||
379 | debug("%s: start", __func__); | ||
380 | |||
381 | PRIVSEP(jpake_step1(pctx->grp, | ||
382 | &pctx->server_id, &pctx->server_id_len, | ||
383 | &pctx->x3, &pctx->x4, &pctx->g_x3, &pctx->g_x4, | ||
384 | &x3_proof, &x3_proof_len, | ||
385 | &x4_proof, &x4_proof_len)); | ||
386 | |||
387 | PRIVSEP(auth2_jpake_get_pwdata(authctxt, &pctx->s, | ||
388 | &hash_scheme, &salt)); | ||
389 | |||
390 | if (!use_privsep) | ||
391 | JPAKE_DEBUG_CTX((pctx, "step 1 sending in %s", __func__)); | ||
392 | |||
393 | packet_start(SSH2_MSG_USERAUTH_JPAKE_SERVER_STEP1); | ||
394 | packet_put_cstring(hash_scheme); | ||
395 | packet_put_cstring(salt); | ||
396 | packet_put_string(pctx->server_id, pctx->server_id_len); | ||
397 | packet_put_bignum2(pctx->g_x3); | ||
398 | packet_put_bignum2(pctx->g_x4); | ||
399 | packet_put_string(x3_proof, x3_proof_len); | ||
400 | packet_put_string(x4_proof, x4_proof_len); | ||
401 | packet_send(); | ||
402 | packet_write_wait(); | ||
403 | |||
404 | bzero(hash_scheme, strlen(hash_scheme)); | ||
405 | bzero(salt, strlen(salt)); | ||
406 | free(hash_scheme); | ||
407 | free(salt); | ||
408 | bzero(x3_proof, x3_proof_len); | ||
409 | bzero(x4_proof, x4_proof_len); | ||
410 | free(x3_proof); | ||
411 | free(x4_proof); | ||
412 | |||
413 | /* Expect step 1 packet from peer */ | ||
414 | dispatch_set(SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP1, | ||
415 | input_userauth_jpake_client_step1); | ||
416 | |||
417 | authctxt->postponed = 1; | ||
418 | return 0; | ||
419 | } | ||
420 | |||
421 | /* ARGSUSED */ | ||
422 | static void | ||
423 | input_userauth_jpake_client_step1(int type, u_int32_t seq, void *ctxt) | ||
424 | { | ||
425 | Authctxt *authctxt = ctxt; | ||
426 | struct jpake_ctx *pctx = authctxt->jpake_ctx; | ||
427 | u_char *x1_proof, *x2_proof, *x4_s_proof; | ||
428 | u_int x1_proof_len, x2_proof_len, x4_s_proof_len; | ||
429 | |||
430 | /* Disable this message */ | ||
431 | dispatch_set(SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP1, NULL); | ||
432 | |||
433 | /* Fetch step 1 values */ | ||
434 | if ((pctx->g_x1 = BN_new()) == NULL || | ||
435 | (pctx->g_x2 = BN_new()) == NULL) | ||
436 | fatal("%s: BN_new", __func__); | ||
437 | pctx->client_id = packet_get_string(&pctx->client_id_len); | ||
438 | packet_get_bignum2(pctx->g_x1); | ||
439 | packet_get_bignum2(pctx->g_x2); | ||
440 | x1_proof = packet_get_string(&x1_proof_len); | ||
441 | x2_proof = packet_get_string(&x2_proof_len); | ||
442 | packet_check_eom(); | ||
443 | |||
444 | if (!use_privsep) | ||
445 | JPAKE_DEBUG_CTX((pctx, "step 1 received in %s", __func__)); | ||
446 | |||
447 | PRIVSEP(jpake_step2(pctx->grp, pctx->s, pctx->g_x3, | ||
448 | pctx->g_x1, pctx->g_x2, pctx->x4, | ||
449 | pctx->client_id, pctx->client_id_len, | ||
450 | pctx->server_id, pctx->server_id_len, | ||
451 | x1_proof, x1_proof_len, | ||
452 | x2_proof, x2_proof_len, | ||
453 | &pctx->b, | ||
454 | &x4_s_proof, &x4_s_proof_len)); | ||
455 | |||
456 | bzero(x1_proof, x1_proof_len); | ||
457 | bzero(x2_proof, x2_proof_len); | ||
458 | free(x1_proof); | ||
459 | free(x2_proof); | ||
460 | |||
461 | if (!use_privsep) | ||
462 | JPAKE_DEBUG_CTX((pctx, "step 2 sending in %s", __func__)); | ||
463 | |||
464 | /* Send values for step 2 */ | ||
465 | packet_start(SSH2_MSG_USERAUTH_JPAKE_SERVER_STEP2); | ||
466 | packet_put_bignum2(pctx->b); | ||
467 | packet_put_string(x4_s_proof, x4_s_proof_len); | ||
468 | packet_send(); | ||
469 | packet_write_wait(); | ||
470 | |||
471 | bzero(x4_s_proof, x4_s_proof_len); | ||
472 | free(x4_s_proof); | ||
473 | |||
474 | /* Expect step 2 packet from peer */ | ||
475 | dispatch_set(SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP2, | ||
476 | input_userauth_jpake_client_step2); | ||
477 | } | ||
478 | |||
479 | /* ARGSUSED */ | ||
480 | static void | ||
481 | input_userauth_jpake_client_step2(int type, u_int32_t seq, void *ctxt) | ||
482 | { | ||
483 | Authctxt *authctxt = ctxt; | ||
484 | struct jpake_ctx *pctx = authctxt->jpake_ctx; | ||
485 | u_char *x2_s_proof; | ||
486 | u_int x2_s_proof_len; | ||
487 | |||
488 | /* Disable this message */ | ||
489 | dispatch_set(SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP2, NULL); | ||
490 | |||
491 | if ((pctx->a = BN_new()) == NULL) | ||
492 | fatal("%s: BN_new", __func__); | ||
493 | |||
494 | /* Fetch step 2 values */ | ||
495 | packet_get_bignum2(pctx->a); | ||
496 | x2_s_proof = packet_get_string(&x2_s_proof_len); | ||
497 | packet_check_eom(); | ||
498 | |||
499 | if (!use_privsep) | ||
500 | JPAKE_DEBUG_CTX((pctx, "step 2 received in %s", __func__)); | ||
501 | |||
502 | /* Derive shared key and calculate confirmation hash */ | ||
503 | PRIVSEP(jpake_key_confirm(pctx->grp, pctx->s, pctx->a, | ||
504 | pctx->x4, pctx->g_x3, pctx->g_x4, pctx->g_x1, pctx->g_x2, | ||
505 | pctx->server_id, pctx->server_id_len, | ||
506 | pctx->client_id, pctx->client_id_len, | ||
507 | session_id2, session_id2_len, | ||
508 | x2_s_proof, x2_s_proof_len, | ||
509 | &pctx->k, | ||
510 | &pctx->h_k_sid_sessid, &pctx->h_k_sid_sessid_len)); | ||
511 | |||
512 | bzero(x2_s_proof, x2_s_proof_len); | ||
513 | free(x2_s_proof); | ||
514 | |||
515 | if (!use_privsep) | ||
516 | JPAKE_DEBUG_CTX((pctx, "confirm sending in %s", __func__)); | ||
517 | |||
518 | /* Send key confirmation proof */ | ||
519 | packet_start(SSH2_MSG_USERAUTH_JPAKE_SERVER_CONFIRM); | ||
520 | packet_put_string(pctx->h_k_sid_sessid, pctx->h_k_sid_sessid_len); | ||
521 | packet_send(); | ||
522 | packet_write_wait(); | ||
523 | |||
524 | /* Expect confirmation from peer */ | ||
525 | dispatch_set(SSH2_MSG_USERAUTH_JPAKE_CLIENT_CONFIRM, | ||
526 | input_userauth_jpake_client_confirm); | ||
527 | } | ||
528 | |||
529 | /* ARGSUSED */ | ||
530 | static void | ||
531 | input_userauth_jpake_client_confirm(int type, u_int32_t seq, void *ctxt) | ||
532 | { | ||
533 | Authctxt *authctxt = ctxt; | ||
534 | struct jpake_ctx *pctx = authctxt->jpake_ctx; | ||
535 | int authenticated = 0; | ||
536 | |||
537 | /* Disable this message */ | ||
538 | dispatch_set(SSH2_MSG_USERAUTH_JPAKE_CLIENT_CONFIRM, NULL); | ||
539 | |||
540 | pctx->h_k_cid_sessid = packet_get_string(&pctx->h_k_cid_sessid_len); | ||
541 | packet_check_eom(); | ||
542 | |||
543 | if (!use_privsep) | ||
544 | JPAKE_DEBUG_CTX((pctx, "confirm received in %s", __func__)); | ||
545 | |||
546 | /* Verify expected confirmation hash */ | ||
547 | if (PRIVSEP(jpake_check_confirm(pctx->k, | ||
548 | pctx->client_id, pctx->client_id_len, | ||
549 | session_id2, session_id2_len, | ||
550 | pctx->h_k_cid_sessid, pctx->h_k_cid_sessid_len)) == 1) | ||
551 | authenticated = authctxt->valid ? 1 : 0; | ||
552 | else | ||
553 | debug("%s: confirmation mismatch", __func__); | ||
554 | |||
555 | /* done */ | ||
556 | authctxt->postponed = 0; | ||
557 | jpake_free(authctxt->jpake_ctx); | ||
558 | authctxt->jpake_ctx = NULL; | ||
559 | userauth_finish(authctxt, authenticated, method_jpake.name, NULL); | ||
560 | } | ||
561 | |||
562 | #endif /* JPAKE */ | ||
563 | |||
diff --git a/auth2-passwd.c b/auth2-passwd.c index 21bc5047d..707680cd0 100644 --- a/auth2-passwd.c +++ b/auth2-passwd.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: auth2-passwd.c,v 1.10 2013/05/17 00:13:13 djm Exp $ */ | 1 | /* $OpenBSD: auth2-passwd.c,v 1.11 2014/02/02 03:44:31 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -59,7 +59,7 @@ userauth_passwd(Authctxt *authctxt) | |||
59 | if (change) { | 59 | if (change) { |
60 | /* discard new password from packet */ | 60 | /* discard new password from packet */ |
61 | newpass = packet_get_string(&newlen); | 61 | newpass = packet_get_string(&newlen); |
62 | memset(newpass, 0, newlen); | 62 | explicit_bzero(newpass, newlen); |
63 | free(newpass); | 63 | free(newpass); |
64 | } | 64 | } |
65 | packet_check_eom(); | 65 | packet_check_eom(); |
@@ -68,7 +68,7 @@ userauth_passwd(Authctxt *authctxt) | |||
68 | logit("password change not supported"); | 68 | logit("password change not supported"); |
69 | else if (PRIVSEP(auth_password(authctxt, password)) == 1) | 69 | else if (PRIVSEP(auth_password(authctxt, password)) == 1) |
70 | authenticated = 1; | 70 | authenticated = 1; |
71 | memset(password, 0, len); | 71 | explicit_bzero(password, len); |
72 | free(password); | 72 | free(password); |
73 | return authenticated; | 73 | return authenticated; |
74 | } | 74 | } |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: auth2.c,v 1.129 2013/05/19 02:42:42 djm Exp $ */ | 1 | /* $OpenBSD: auth2.c,v 1.130 2014/01/29 06:18:35 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -71,9 +71,6 @@ extern Authmethod method_hostbased; | |||
71 | #ifdef GSSAPI | 71 | #ifdef GSSAPI |
72 | extern Authmethod method_gssapi; | 72 | extern Authmethod method_gssapi; |
73 | #endif | 73 | #endif |
74 | #ifdef JPAKE | ||
75 | extern Authmethod method_jpake; | ||
76 | #endif | ||
77 | 74 | ||
78 | Authmethod *authmethods[] = { | 75 | Authmethod *authmethods[] = { |
79 | &method_none, | 76 | &method_none, |
@@ -81,9 +78,6 @@ Authmethod *authmethods[] = { | |||
81 | #ifdef GSSAPI | 78 | #ifdef GSSAPI |
82 | &method_gssapi, | 79 | &method_gssapi, |
83 | #endif | 80 | #endif |
84 | #ifdef JPAKE | ||
85 | &method_jpake, | ||
86 | #endif | ||
87 | &method_passwd, | 81 | &method_passwd, |
88 | &method_kbdint, | 82 | &method_kbdint, |
89 | &method_hostbased, | 83 | &method_hostbased, |
@@ -270,9 +264,6 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt) | |||
270 | } | 264 | } |
271 | /* reset state */ | 265 | /* reset state */ |
272 | auth2_challenge_stop(authctxt); | 266 | auth2_challenge_stop(authctxt); |
273 | #ifdef JPAKE | ||
274 | auth2_jpake_stop(authctxt); | ||
275 | #endif | ||
276 | 267 | ||
277 | #ifdef GSSAPI | 268 | #ifdef GSSAPI |
278 | /* XXX move to auth2_gssapi_stop() */ | 269 | /* XXX move to auth2_gssapi_stop() */ |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: authfd.c,v 1.91 2013/12/29 04:29:25 djm Exp $ */ | 1 | /* $OpenBSD: authfd.c,v 1.92 2014/01/31 16:39:19 tedu Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -102,7 +102,7 @@ ssh_get_authentication_socket(void) | |||
102 | if (!authsocket) | 102 | if (!authsocket) |
103 | return -1; | 103 | return -1; |
104 | 104 | ||
105 | bzero(&sunaddr, sizeof(sunaddr)); | 105 | memset(&sunaddr, 0, sizeof(sunaddr)); |
106 | sunaddr.sun_family = AF_UNIX; | 106 | sunaddr.sun_family = AF_UNIX; |
107 | strlcpy(sunaddr.sun_path, authsocket, sizeof(sunaddr.sun_path)); | 107 | strlcpy(sunaddr.sun_path, authsocket, sizeof(sunaddr.sun_path)); |
108 | 108 | ||
diff --git a/authfile.c b/authfile.c index 7eccbb2c9..d7eaa9dec 100644 --- a/authfile.c +++ b/authfile.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: authfile.c,v 1.101 2013/12/29 04:35:50 djm Exp $ */ | 1 | /* $OpenBSD: authfile.c,v 1.103 2014/02/02 03:44:31 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * 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, | |||
131 | buffer_put_int(&kdf, rounds); | 131 | buffer_put_int(&kdf, rounds); |
132 | } | 132 | } |
133 | cipher_init(&ctx, c, key, keylen, key + keylen , ivlen, 1); | 133 | cipher_init(&ctx, c, key, keylen, key + keylen , ivlen, 1); |
134 | memset(key, 0, keylen + ivlen); | 134 | explicit_bzero(key, keylen + ivlen); |
135 | free(key); | 135 | free(key); |
136 | 136 | ||
137 | buffer_init(&encoded); | 137 | buffer_init(&encoded); |
@@ -143,7 +143,7 @@ key_private_to_blob2(Key *prv, Buffer *blob, const char *passphrase, | |||
143 | key_to_blob(prv, &cp, &len); /* public key */ | 143 | key_to_blob(prv, &cp, &len); /* public key */ |
144 | buffer_put_string(&encoded, cp, len); | 144 | buffer_put_string(&encoded, cp, len); |
145 | 145 | ||
146 | memset(cp, 0, len); | 146 | explicit_bzero(cp, len); |
147 | free(cp); | 147 | free(cp); |
148 | 148 | ||
149 | buffer_free(&kdf); | 149 | buffer_free(&kdf); |
@@ -409,7 +409,7 @@ key_parse_private2(Buffer *blob, int type, const char *passphrase, | |||
409 | free(salt); | 409 | free(salt); |
410 | free(comment); | 410 | free(comment); |
411 | if (key) | 411 | if (key) |
412 | memset(key, 0, keylen + ivlen); | 412 | explicit_bzero(key, keylen + ivlen); |
413 | free(key); | 413 | free(key); |
414 | buffer_free(&encoded); | 414 | buffer_free(&encoded); |
415 | buffer_free(©); | 415 | buffer_free(©); |
@@ -496,10 +496,10 @@ key_private_rsa1_to_blob(Key *key, Buffer *blob, const char *passphrase, | |||
496 | buffer_ptr(&buffer), buffer_len(&buffer), 0, 0) != 0) | 496 | buffer_ptr(&buffer), buffer_len(&buffer), 0, 0) != 0) |
497 | fatal("%s: cipher_crypt failed", __func__); | 497 | fatal("%s: cipher_crypt failed", __func__); |
498 | cipher_cleanup(&ciphercontext); | 498 | cipher_cleanup(&ciphercontext); |
499 | memset(&ciphercontext, 0, sizeof(ciphercontext)); | 499 | explicit_bzero(&ciphercontext, sizeof(ciphercontext)); |
500 | 500 | ||
501 | /* Destroy temporary data. */ | 501 | /* Destroy temporary data. */ |
502 | memset(buf, 0, sizeof(buf)); | 502 | explicit_bzero(buf, sizeof(buf)); |
503 | buffer_free(&buffer); | 503 | buffer_free(&buffer); |
504 | 504 | ||
505 | buffer_append(blob, buffer_ptr(&encrypted), buffer_len(&encrypted)); | 505 | buffer_append(blob, buffer_ptr(&encrypted), buffer_len(&encrypted)); |
@@ -703,17 +703,17 @@ key_load_file(int fd, const char *filename, Buffer *blob) | |||
703 | __func__, filename == NULL ? "" : filename, | 703 | __func__, filename == NULL ? "" : filename, |
704 | filename == NULL ? "" : " ", strerror(errno)); | 704 | filename == NULL ? "" : " ", strerror(errno)); |
705 | buffer_clear(blob); | 705 | buffer_clear(blob); |
706 | bzero(buf, sizeof(buf)); | 706 | explicit_bzero(buf, sizeof(buf)); |
707 | return 0; | 707 | return 0; |
708 | } | 708 | } |
709 | buffer_append(blob, buf, len); | 709 | buffer_append(blob, buf, len); |
710 | if (buffer_len(blob) > MAX_KEY_FILE_SIZE) { | 710 | if (buffer_len(blob) > MAX_KEY_FILE_SIZE) { |
711 | buffer_clear(blob); | 711 | buffer_clear(blob); |
712 | bzero(buf, sizeof(buf)); | 712 | explicit_bzero(buf, sizeof(buf)); |
713 | goto toobig; | 713 | goto toobig; |
714 | } | 714 | } |
715 | } | 715 | } |
716 | bzero(buf, sizeof(buf)); | 716 | explicit_bzero(buf, sizeof(buf)); |
717 | if ((st.st_mode & (S_IFSOCK|S_IFCHR|S_IFIFO)) == 0 && | 717 | if ((st.st_mode & (S_IFSOCK|S_IFCHR|S_IFIFO)) == 0 && |
718 | st.st_size != buffer_len(blob)) { | 718 | st.st_size != buffer_len(blob)) { |
719 | debug("%s: key file %.200s%schanged size while reading", | 719 | debug("%s: key file %.200s%schanged size while reading", |
@@ -831,7 +831,7 @@ key_parse_private_rsa1(Buffer *blob, const char *passphrase, char **commentp) | |||
831 | buffer_ptr(©), buffer_len(©), 0, 0) != 0) | 831 | buffer_ptr(©), buffer_len(©), 0, 0) != 0) |
832 | fatal("%s: cipher_crypt failed", __func__); | 832 | fatal("%s: cipher_crypt failed", __func__); |
833 | cipher_cleanup(&ciphercontext); | 833 | cipher_cleanup(&ciphercontext); |
834 | memset(&ciphercontext, 0, sizeof(ciphercontext)); | 834 | explicit_bzero(&ciphercontext, sizeof(ciphercontext)); |
835 | buffer_free(©); | 835 | buffer_free(©); |
836 | 836 | ||
837 | check1 = buffer_get_char(&decrypted); | 837 | check1 = buffer_get_char(&decrypted); |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: bufaux.c,v 1.54 2014/01/12 08:13:13 djm Exp $ */ | 1 | /* $OpenBSD: bufaux.c,v 1.56 2014/02/02 03:44:31 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * 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) | |||
216 | if (cp == ret + length - 1) | 216 | if (cp == ret + length - 1) |
217 | error("buffer_get_cstring_ret: string contains \\0"); | 217 | error("buffer_get_cstring_ret: string contains \\0"); |
218 | else { | 218 | else { |
219 | bzero(ret, length); | 219 | explicit_bzero(ret, length); |
220 | free(ret); | 220 | free(ret); |
221 | return NULL; | 221 | return NULL; |
222 | } | 222 | } |
@@ -346,7 +346,7 @@ buffer_get_bignum2_as_string_ret(Buffer *buffer, u_int *length_ptr) | |||
346 | } | 346 | } |
347 | ret = xmalloc(len); | 347 | ret = xmalloc(len); |
348 | memcpy(ret, p, len); | 348 | memcpy(ret, p, len); |
349 | memset(p, '\0', len); | 349 | explicit_bzero(p, len); |
350 | free(bin); | 350 | free(bin); |
351 | return ret; | 351 | return ret; |
352 | } | 352 | } |
@@ -383,7 +383,7 @@ buffer_put_bignum2_from_string(Buffer *buffer, const u_char *s, u_int l) | |||
383 | } | 383 | } |
384 | memcpy(p, s, l); | 384 | memcpy(p, s, l); |
385 | buffer_put_string(buffer, buf, l + pad); | 385 | buffer_put_string(buffer, buf, l + pad); |
386 | memset(buf, '\0', l + pad); | 386 | explicit_bzero(buf, l + pad); |
387 | free(buf); | 387 | free(buf); |
388 | } | 388 | } |
389 | 389 | ||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: bufbn.c,v 1.8 2013/11/08 11:15:19 dtucker Exp $*/ | 1 | /* $OpenBSD: bufbn.c,v 1.11 2014/02/27 08:25:09 djm Exp $*/ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -80,7 +80,7 @@ buffer_put_bignum_ret(Buffer *buffer, const BIGNUM *value) | |||
80 | /* Store the binary data. */ | 80 | /* Store the binary data. */ |
81 | buffer_append(buffer, buf, oi); | 81 | buffer_append(buffer, buf, oi); |
82 | 82 | ||
83 | memset(buf, 0, bin_size); | 83 | explicit_bzero(buf, bin_size); |
84 | free(buf); | 84 | free(buf); |
85 | 85 | ||
86 | return (0); | 86 | return (0); |
@@ -108,6 +108,11 @@ buffer_get_bignum_ret(Buffer *buffer, BIGNUM *value) | |||
108 | return (-1); | 108 | return (-1); |
109 | } | 109 | } |
110 | bits = get_u16(buf); | 110 | bits = get_u16(buf); |
111 | if (bits > 65535-7) { | ||
112 | error("buffer_get_bignum_ret: cannot handle BN of size %d", | ||
113 | bits); | ||
114 | return (-1); | ||
115 | } | ||
111 | /* Compute the number of binary bytes that follow. */ | 116 | /* Compute the number of binary bytes that follow. */ |
112 | bytes = (bits + 7) / 8; | 117 | bytes = (bits + 7) / 8; |
113 | if (bytes > 8 * 1024) { | 118 | if (bytes > 8 * 1024) { |
@@ -173,7 +178,7 @@ buffer_put_bignum2_ret(Buffer *buffer, const BIGNUM *value) | |||
173 | } | 178 | } |
174 | hasnohigh = (buf[1] & 0x80) ? 0 : 1; | 179 | hasnohigh = (buf[1] & 0x80) ? 0 : 1; |
175 | buffer_put_string(buffer, buf+hasnohigh, bytes-hasnohigh); | 180 | buffer_put_string(buffer, buf+hasnohigh, bytes-hasnohigh); |
176 | memset(buf, 0, bytes); | 181 | explicit_bzero(buf, bytes); |
177 | free(buf); | 182 | free(buf); |
178 | return (0); | 183 | return (0); |
179 | } | 184 | } |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: bufec.c,v 1.2 2013/05/17 00:13:13 djm Exp $ */ | 1 | /* $OpenBSD: bufec.c,v 1.3 2014/01/31 16:39:19 tedu Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2010 Damien Miller <djm@mindrot.org> | 3 | * Copyright (c) 2010 Damien Miller <djm@mindrot.org> |
4 | * | 4 | * |
@@ -77,7 +77,7 @@ buffer_put_ecpoint_ret(Buffer *buffer, const EC_GROUP *curve, | |||
77 | ret = 0; | 77 | ret = 0; |
78 | out: | 78 | out: |
79 | if (buf != NULL) { | 79 | if (buf != NULL) { |
80 | bzero(buf, len); | 80 | explicit_bzero(buf, len); |
81 | free(buf); | 81 | free(buf); |
82 | } | 82 | } |
83 | BN_CTX_free(bnctx); | 83 | BN_CTX_free(bnctx); |
@@ -130,7 +130,7 @@ buffer_get_ecpoint_ret(Buffer *buffer, const EC_GROUP *curve, | |||
130 | ret = 0; | 130 | ret = 0; |
131 | out: | 131 | out: |
132 | BN_CTX_free(bnctx); | 132 | BN_CTX_free(bnctx); |
133 | bzero(buf, len); | 133 | explicit_bzero(buf, len); |
134 | free(buf); | 134 | free(buf); |
135 | return ret; | 135 | return ret; |
136 | } | 136 | } |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: buffer.c,v 1.34 2013/11/08 11:15:19 dtucker Exp $ */ | 1 | /* $OpenBSD: buffer.c,v 1.35 2014/02/02 03:44:31 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -49,7 +49,7 @@ void | |||
49 | buffer_free(Buffer *buffer) | 49 | buffer_free(Buffer *buffer) |
50 | { | 50 | { |
51 | if (buffer->alloc > 0) { | 51 | if (buffer->alloc > 0) { |
52 | memset(buffer->buf, 0, buffer->alloc); | 52 | explicit_bzero(buffer->buf, buffer->alloc); |
53 | buffer->alloc = 0; | 53 | buffer->alloc = 0; |
54 | free(buffer->buf); | 54 | free(buffer->buf); |
55 | } | 55 | } |
diff --git a/canohost.c b/canohost.c index a19a60cda..a61a8c94d 100644 --- a/canohost.c +++ b/canohost.c | |||
@@ -192,7 +192,7 @@ ipv64_normalise_mapped(struct sockaddr_storage *addr, socklen_t *len) | |||
192 | memcpy(&inaddr, ((char *)&a6->sin6_addr) + 12, sizeof(inaddr)); | 192 | memcpy(&inaddr, ((char *)&a6->sin6_addr) + 12, sizeof(inaddr)); |
193 | port = a6->sin6_port; | 193 | port = a6->sin6_port; |
194 | 194 | ||
195 | bzero(a4, sizeof(*a4)); | 195 | memset(a4, 0, sizeof(*a4)); |
196 | 196 | ||
197 | a4->sin_family = AF_INET; | 197 | a4->sin_family = AF_INET; |
198 | *len = sizeof(*a4); | 198 | *len = sizeof(*a4); |
diff --git a/channels.c b/channels.c index e741f29b9..9efe89c9c 100644 --- a/channels.c +++ b/channels.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: channels.c,v 1.328 2013/12/19 01:04:36 djm Exp $ */ | 1 | /* $OpenBSD: channels.c,v 1.331 2014/02/26 20:29:29 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -423,7 +423,7 @@ channel_free(Channel *c) | |||
423 | if (cc->abandon_cb != NULL) | 423 | if (cc->abandon_cb != NULL) |
424 | cc->abandon_cb(c, cc->ctx); | 424 | cc->abandon_cb(c, cc->ctx); |
425 | TAILQ_REMOVE(&c->status_confirms, cc, entry); | 425 | TAILQ_REMOVE(&c->status_confirms, cc, entry); |
426 | bzero(cc, sizeof(*cc)); | 426 | explicit_bzero(cc, sizeof(*cc)); |
427 | free(cc); | 427 | free(cc); |
428 | } | 428 | } |
429 | if (c->filter_cleanup != NULL && c->filter_ctx != NULL) | 429 | if (c->filter_cleanup != NULL && c->filter_ctx != NULL) |
@@ -1072,6 +1072,9 @@ channel_decode_socks4(Channel *c, fd_set *readset, fd_set *writeset) | |||
1072 | buffer_get(&c->input, (char *)&s4_req.dest_addr, 4); | 1072 | buffer_get(&c->input, (char *)&s4_req.dest_addr, 4); |
1073 | have = buffer_len(&c->input); | 1073 | have = buffer_len(&c->input); |
1074 | p = buffer_ptr(&c->input); | 1074 | p = buffer_ptr(&c->input); |
1075 | if (memchr(p, '\0', have) == NULL) | ||
1076 | fatal("channel %d: decode socks4: user not nul terminated", | ||
1077 | c->self); | ||
1075 | len = strlen(p); | 1078 | len = strlen(p); |
1076 | debug2("channel %d: decode socks4: user %s/%d", c->self, p, len); | 1079 | debug2("channel %d: decode socks4: user %s/%d", c->self, p, len); |
1077 | len++; /* trailing '\0' */ | 1080 | len++; /* trailing '\0' */ |
@@ -1386,7 +1389,7 @@ port_open_helper(Channel *c, char *rtype) | |||
1386 | int direct; | 1389 | int direct; |
1387 | char buf[1024]; | 1390 | char buf[1024]; |
1388 | char *local_ipaddr = get_local_ipaddr(c->sock); | 1391 | char *local_ipaddr = get_local_ipaddr(c->sock); |
1389 | int local_port = get_sock_port(c->sock, 1); | 1392 | int local_port = c->sock == -1 ? 65536 : get_sock_port(c->sock, 1); |
1390 | char *remote_ipaddr = get_peer_ipaddr(c->sock); | 1393 | char *remote_ipaddr = get_peer_ipaddr(c->sock); |
1391 | int remote_port = get_peer_port(c->sock); | 1394 | int remote_port = get_peer_port(c->sock); |
1392 | 1395 | ||
@@ -2671,7 +2674,7 @@ channel_input_status_confirm(int type, u_int32_t seq, void *ctxt) | |||
2671 | return; | 2674 | return; |
2672 | cc->cb(type, c, cc->ctx); | 2675 | cc->cb(type, c, cc->ctx); |
2673 | TAILQ_REMOVE(&c->status_confirms, cc, entry); | 2676 | TAILQ_REMOVE(&c->status_confirms, cc, entry); |
2674 | bzero(cc, sizeof(*cc)); | 2677 | explicit_bzero(cc, sizeof(*cc)); |
2675 | free(cc); | 2678 | free(cc); |
2676 | } | 2679 | } |
2677 | 2680 | ||
@@ -3304,9 +3307,7 @@ channel_connect_ctx_free(struct channel_connect *cctx) | |||
3304 | free(cctx->host); | 3307 | free(cctx->host); |
3305 | if (cctx->aitop) | 3308 | if (cctx->aitop) |
3306 | freeaddrinfo(cctx->aitop); | 3309 | freeaddrinfo(cctx->aitop); |
3307 | bzero(cctx, sizeof(*cctx)); | 3310 | memset(cctx, 0, sizeof(*cctx)); |
3308 | cctx->host = NULL; | ||
3309 | cctx->ai = cctx->aitop = NULL; | ||
3310 | } | 3311 | } |
3311 | 3312 | ||
3312 | /* Return CONNECTING channel to remote host, port */ | 3313 | /* Return CONNECTING channel to remote host, port */ |
diff --git a/cipher-3des1.c b/cipher-3des1.c index 56fc77786..b2823592b 100644 --- a/cipher-3des1.c +++ b/cipher-3des1.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: cipher-3des1.c,v 1.9 2013/11/08 00:39:15 djm Exp $ */ | 1 | /* $OpenBSD: cipher-3des1.c,v 1.10 2014/02/02 03:44:31 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2003 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2003 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -93,7 +93,7 @@ ssh1_3des_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv, | |||
93 | if (EVP_CipherInit(&c->k1, EVP_des_cbc(), k1, NULL, enc) == 0 || | 93 | if (EVP_CipherInit(&c->k1, EVP_des_cbc(), k1, NULL, enc) == 0 || |
94 | EVP_CipherInit(&c->k2, EVP_des_cbc(), k2, NULL, !enc) == 0 || | 94 | EVP_CipherInit(&c->k2, EVP_des_cbc(), k2, NULL, !enc) == 0 || |
95 | EVP_CipherInit(&c->k3, EVP_des_cbc(), k3, NULL, enc) == 0) { | 95 | EVP_CipherInit(&c->k3, EVP_des_cbc(), k3, NULL, enc) == 0) { |
96 | memset(c, 0, sizeof(*c)); | 96 | explicit_bzero(c, sizeof(*c)); |
97 | free(c); | 97 | free(c); |
98 | EVP_CIPHER_CTX_set_app_data(ctx, NULL); | 98 | EVP_CIPHER_CTX_set_app_data(ctx, NULL); |
99 | return (0); | 99 | return (0); |
@@ -134,7 +134,7 @@ ssh1_3des_cleanup(EVP_CIPHER_CTX *ctx) | |||
134 | EVP_CIPHER_CTX_cleanup(&c->k1); | 134 | EVP_CIPHER_CTX_cleanup(&c->k1); |
135 | EVP_CIPHER_CTX_cleanup(&c->k2); | 135 | EVP_CIPHER_CTX_cleanup(&c->k2); |
136 | EVP_CIPHER_CTX_cleanup(&c->k3); | 136 | EVP_CIPHER_CTX_cleanup(&c->k3); |
137 | memset(c, 0, sizeof(*c)); | 137 | explicit_bzero(c, sizeof(*c)); |
138 | free(c); | 138 | free(c); |
139 | EVP_CIPHER_CTX_set_app_data(ctx, NULL); | 139 | EVP_CIPHER_CTX_set_app_data(ctx, NULL); |
140 | } | 140 | } |
diff --git a/cipher-chachapoly.c b/cipher-chachapoly.c index 91b0830fd..251b94ec8 100644 --- a/cipher-chachapoly.c +++ b/cipher-chachapoly.c | |||
@@ -14,7 +14,7 @@ | |||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
15 | */ | 15 | */ |
16 | 16 | ||
17 | /* $OpenBSD: cipher-chachapoly.c,v 1.3 2013/12/15 21:42:35 djm Exp $ */ | 17 | /* $OpenBSD: cipher-chachapoly.c,v 1.4 2014/01/31 16:39:19 tedu Exp $ */ |
18 | 18 | ||
19 | #include "includes.h" | 19 | #include "includes.h" |
20 | 20 | ||
@@ -58,7 +58,7 @@ chachapoly_crypt(struct chachapoly_ctx *ctx, u_int seqnr, u_char *dest, | |||
58 | * Run ChaCha20 once to generate the Poly1305 key. The IV is the | 58 | * Run ChaCha20 once to generate the Poly1305 key. The IV is the |
59 | * packet sequence number. | 59 | * packet sequence number. |
60 | */ | 60 | */ |
61 | bzero(poly_key, sizeof(poly_key)); | 61 | memset(poly_key, 0, sizeof(poly_key)); |
62 | put_u64(seqbuf, seqnr); | 62 | put_u64(seqbuf, seqnr); |
63 | chacha_ivsetup(&ctx->main_ctx, seqbuf, NULL); | 63 | chacha_ivsetup(&ctx->main_ctx, seqbuf, NULL); |
64 | chacha_encrypt_bytes(&ctx->main_ctx, | 64 | chacha_encrypt_bytes(&ctx->main_ctx, |
@@ -90,9 +90,9 @@ chachapoly_crypt(struct chachapoly_ctx *ctx, u_int seqnr, u_char *dest, | |||
90 | r = 0; | 90 | r = 0; |
91 | 91 | ||
92 | out: | 92 | out: |
93 | bzero(expected_tag, sizeof(expected_tag)); | 93 | explicit_bzero(expected_tag, sizeof(expected_tag)); |
94 | bzero(seqbuf, sizeof(seqbuf)); | 94 | explicit_bzero(seqbuf, sizeof(seqbuf)); |
95 | bzero(poly_key, sizeof(poly_key)); | 95 | explicit_bzero(poly_key, sizeof(poly_key)); |
96 | return r; | 96 | return r; |
97 | } | 97 | } |
98 | 98 | ||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: cipher.c,v 1.94 2014/01/25 10:12:50 dtucker Exp $ */ | 1 | /* $OpenBSD: cipher.c,v 1.97 2014/02/07 06:55:54 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -39,8 +39,6 @@ | |||
39 | 39 | ||
40 | #include <sys/types.h> | 40 | #include <sys/types.h> |
41 | 41 | ||
42 | #include <openssl/md5.h> | ||
43 | |||
44 | #include <string.h> | 42 | #include <string.h> |
45 | #include <stdarg.h> | 43 | #include <stdarg.h> |
46 | #include <stdio.h> | 44 | #include <stdio.h> |
@@ -49,6 +47,8 @@ | |||
49 | #include "log.h" | 47 | #include "log.h" |
50 | #include "misc.h" | 48 | #include "misc.h" |
51 | #include "cipher.h" | 49 | #include "cipher.h" |
50 | #include "buffer.h" | ||
51 | #include "digest.h" | ||
52 | 52 | ||
53 | /* compatibility with old or broken OpenSSL versions */ | 53 | /* compatibility with old or broken OpenSSL versions */ |
54 | #include "openbsd-compat/openssl-compat.h" | 54 | #include "openbsd-compat/openssl-compat.h" |
@@ -228,8 +228,6 @@ ciphers_valid(const char *names) | |||
228 | debug("bad cipher %s [%s]", p, names); | 228 | debug("bad cipher %s [%s]", p, names); |
229 | free(cipher_list); | 229 | free(cipher_list); |
230 | return 0; | 230 | return 0; |
231 | } else { | ||
232 | debug3("cipher ok: %s [%s]", p, names); | ||
233 | } | 231 | } |
234 | } | 232 | } |
235 | debug3("ciphers ok: [%s]", names); | 233 | debug3("ciphers ok: [%s]", names); |
@@ -337,7 +335,7 @@ cipher_init(CipherContext *cc, const Cipher *cipher, | |||
337 | if (EVP_Cipher(&cc->evp, discard, junk, | 335 | if (EVP_Cipher(&cc->evp, discard, junk, |
338 | cipher->discard_len) == 0) | 336 | cipher->discard_len) == 0) |
339 | fatal("evp_crypt: EVP_Cipher failed during discard"); | 337 | fatal("evp_crypt: EVP_Cipher failed during discard"); |
340 | memset(discard, 0, cipher->discard_len); | 338 | explicit_bzero(discard, cipher->discard_len); |
341 | free(junk); | 339 | free(junk); |
342 | free(discard); | 340 | free(discard); |
343 | } | 341 | } |
@@ -422,7 +420,7 @@ void | |||
422 | cipher_cleanup(CipherContext *cc) | 420 | cipher_cleanup(CipherContext *cc) |
423 | { | 421 | { |
424 | if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) | 422 | if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) |
425 | memset(&cc->cp_ctx, 0, sizeof(cc->cp_ctx)); | 423 | explicit_bzero(&cc->cp_ctx, sizeof(cc->cp_ctx)); |
426 | else if (EVP_CIPHER_CTX_cleanup(&cc->evp) == 0) | 424 | else if (EVP_CIPHER_CTX_cleanup(&cc->evp) == 0) |
427 | error("cipher_cleanup: EVP_CIPHER_CTX_cleanup failed"); | 425 | error("cipher_cleanup: EVP_CIPHER_CTX_cleanup failed"); |
428 | } | 426 | } |
@@ -436,17 +434,15 @@ void | |||
436 | cipher_set_key_string(CipherContext *cc, const Cipher *cipher, | 434 | cipher_set_key_string(CipherContext *cc, const Cipher *cipher, |
437 | const char *passphrase, int do_encrypt) | 435 | const char *passphrase, int do_encrypt) |
438 | { | 436 | { |
439 | MD5_CTX md; | ||
440 | u_char digest[16]; | 437 | u_char digest[16]; |
441 | 438 | ||
442 | MD5_Init(&md); | 439 | if (ssh_digest_memory(SSH_DIGEST_MD5, passphrase, strlen(passphrase), |
443 | MD5_Update(&md, (const u_char *)passphrase, strlen(passphrase)); | 440 | digest, sizeof(digest)) < 0) |
444 | MD5_Final(digest, &md); | 441 | fatal("%s: md5 failed", __func__); |
445 | 442 | ||
446 | cipher_init(cc, cipher, digest, 16, NULL, 0, do_encrypt); | 443 | cipher_init(cc, cipher, digest, 16, NULL, 0, do_encrypt); |
447 | 444 | ||
448 | memset(digest, 0, sizeof(digest)); | 445 | explicit_bzero(digest, sizeof(digest)); |
449 | memset(&md, 0, sizeof(md)); | ||
450 | } | 446 | } |
451 | 447 | ||
452 | /* | 448 | /* |
diff --git a/clientloop.c b/clientloop.c index f30c8b6b5..59ad3a2c3 100644 --- a/clientloop.c +++ b/clientloop.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: clientloop.c,v 1.256 2013/11/20 20:54:10 deraadt Exp $ */ | 1 | /* $OpenBSD: clientloop.c,v 1.258 2014/02/02 03:44:31 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * 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) | |||
549 | gc->cb(type, seq, gc->ctx); | 549 | gc->cb(type, seq, gc->ctx); |
550 | if (--gc->ref_count <= 0) { | 550 | if (--gc->ref_count <= 0) { |
551 | TAILQ_REMOVE(&global_confirms, gc, entry); | 551 | TAILQ_REMOVE(&global_confirms, gc, entry); |
552 | bzero(gc, sizeof(*gc)); | 552 | explicit_bzero(gc, sizeof(*gc)); |
553 | free(gc); | 553 | free(gc); |
554 | } | 554 | } |
555 | 555 | ||
@@ -876,7 +876,7 @@ process_cmdline(void) | |||
876 | int cancel_port, ok; | 876 | int cancel_port, ok; |
877 | Forward fwd; | 877 | Forward fwd; |
878 | 878 | ||
879 | bzero(&fwd, sizeof(fwd)); | 879 | memset(&fwd, 0, sizeof(fwd)); |
880 | fwd.listen_host = fwd.connect_host = NULL; | 880 | fwd.listen_host = fwd.connect_host = NULL; |
881 | 881 | ||
882 | leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE); | 882 | 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) | |||
1761 | char *data = packet_get_string(&data_len); | 1761 | char *data = packet_get_string(&data_len); |
1762 | packet_check_eom(); | 1762 | packet_check_eom(); |
1763 | buffer_append(&stdout_buffer, data, data_len); | 1763 | buffer_append(&stdout_buffer, data, data_len); |
1764 | memset(data, 0, data_len); | 1764 | explicit_bzero(data, data_len); |
1765 | free(data); | 1765 | free(data); |
1766 | } | 1766 | } |
1767 | static void | 1767 | static void |
@@ -1771,7 +1771,7 @@ client_input_stderr_data(int type, u_int32_t seq, void *ctxt) | |||
1771 | char *data = packet_get_string(&data_len); | 1771 | char *data = packet_get_string(&data_len); |
1772 | packet_check_eom(); | 1772 | packet_check_eom(); |
1773 | buffer_append(&stderr_buffer, data, data_len); | 1773 | buffer_append(&stderr_buffer, data, data_len); |
1774 | memset(data, 0, data_len); | 1774 | explicit_bzero(data, data_len); |
1775 | free(data); | 1775 | free(data); |
1776 | } | 1776 | } |
1777 | static void | 1777 | static void |
diff --git a/config.h.in b/config.h.in index 075c619f6..0401ad181 100644 --- a/config.h.in +++ b/config.h.in | |||
@@ -414,6 +414,9 @@ | |||
414 | /* Define to 1 if you have the `EVP_MD_CTX_cleanup' function. */ | 414 | /* Define to 1 if you have the `EVP_MD_CTX_cleanup' function. */ |
415 | #undef HAVE_EVP_MD_CTX_CLEANUP | 415 | #undef HAVE_EVP_MD_CTX_CLEANUP |
416 | 416 | ||
417 | /* Define to 1 if you have the `EVP_MD_CTX_copy_ex' function. */ | ||
418 | #undef HAVE_EVP_MD_CTX_COPY_EX | ||
419 | |||
417 | /* Define to 1 if you have the `EVP_MD_CTX_init' function. */ | 420 | /* Define to 1 if you have the `EVP_MD_CTX_init' function. */ |
418 | #undef HAVE_EVP_MD_CTX_INIT | 421 | #undef HAVE_EVP_MD_CTX_INIT |
419 | 422 | ||
@@ -423,6 +426,9 @@ | |||
423 | /* Define if you have ut_exit in utmp.h */ | 426 | /* Define if you have ut_exit in utmp.h */ |
424 | #undef HAVE_EXIT_IN_UTMP | 427 | #undef HAVE_EXIT_IN_UTMP |
425 | 428 | ||
429 | /* Define to 1 if you have the `explicit_bzero' function. */ | ||
430 | #undef HAVE_EXPLICIT_BZERO | ||
431 | |||
426 | /* Define to 1 if you have the `fchmod' function. */ | 432 | /* Define to 1 if you have the `fchmod' function. */ |
427 | #undef HAVE_FCHMOD | 433 | #undef HAVE_FCHMOD |
428 | 434 | ||
@@ -1,5 +1,5 @@ | |||
1 | #! /bin/sh | 1 | #! /bin/sh |
2 | # From configure.ac Revision: 1.568 . | 2 | # From configure.ac Revision: 1.571 . |
3 | # Guess values for system-dependent variables and create Makefiles. | 3 | # Guess values for system-dependent variables and create Makefiles. |
4 | # Generated by GNU Autoconf 2.68 for OpenSSH Portable. | 4 | # Generated by GNU Autoconf 2.68 for OpenSSH Portable. |
5 | # | 5 | # |
@@ -7607,7 +7607,7 @@ $as_echo "#define BROKEN_STRNVIS 1" >>confdefs.h | |||
7607 | # and will crash if they cannot be opened. | 7607 | # and will crash if they cannot be opened. |
7608 | 7608 | ||
7609 | $as_echo "#define SANDBOX_SKIP_RLIMIT_NOFILE 1" >>confdefs.h | 7609 | $as_echo "#define SANDBOX_SKIP_RLIMIT_NOFILE 1" >>confdefs.h |
7610 | ], | 7610 | |
7611 | ;; | 7611 | ;; |
7612 | *-*-bsdi*) | 7612 | *-*-bsdi*) |
7613 | $as_echo "#define SETEUID_BREAKS_SETUID 1" >>confdefs.h | 7613 | $as_echo "#define SETEUID_BREAKS_SETUID 1" >>confdefs.h |
@@ -10366,6 +10366,7 @@ for ac_func in \ | |||
10366 | closefrom \ | 10366 | closefrom \ |
10367 | dirfd \ | 10367 | dirfd \ |
10368 | endgrent \ | 10368 | endgrent \ |
10369 | explicit_bzero \ | ||
10369 | fchmod \ | 10370 | fchmod \ |
10370 | fchown \ | 10371 | fchown \ |
10371 | freeaddrinfo \ | 10372 | freeaddrinfo \ |
@@ -12113,6 +12114,7 @@ for ac_func in \ | |||
12113 | EVP_DigestFinal_ex \ | 12114 | EVP_DigestFinal_ex \ |
12114 | EVP_MD_CTX_init \ | 12115 | EVP_MD_CTX_init \ |
12115 | EVP_MD_CTX_cleanup \ | 12116 | EVP_MD_CTX_cleanup \ |
12117 | EVP_MD_CTX_copy_ex \ | ||
12116 | HMAC_CTX_init \ | 12118 | HMAC_CTX_init \ |
12117 | RSA_generate_key_ex \ | 12119 | RSA_generate_key_ex \ |
12118 | RSA_get_default_method \ | 12120 | RSA_get_default_method \ |
diff --git a/configure.ac b/configure.ac index dfd32cd85..7c6ce08d8 100644 --- a/configure.ac +++ b/configure.ac | |||
@@ -1,4 +1,4 @@ | |||
1 | # $Id: configure.ac,v 1.568 2014/01/30 00:26:46 djm Exp $ | 1 | # $Id: configure.ac,v 1.571 2014/02/21 17:09:34 tim Exp $ |
2 | # | 2 | # |
3 | # Copyright (c) 1999-2004 Damien Miller | 3 | # Copyright (c) 1999-2004 Damien Miller |
4 | # | 4 | # |
@@ -15,7 +15,7 @@ | |||
15 | # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | 15 | # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
16 | 16 | ||
17 | AC_INIT([OpenSSH], [Portable], [openssh-unix-dev@mindrot.org]) | 17 | AC_INIT([OpenSSH], [Portable], [openssh-unix-dev@mindrot.org]) |
18 | AC_REVISION($Revision: 1.568 $) | 18 | AC_REVISION($Revision: 1.571 $) |
19 | AC_CONFIG_SRCDIR([ssh.c]) | 19 | AC_CONFIG_SRCDIR([ssh.c]) |
20 | AC_LANG([C]) | 20 | AC_LANG([C]) |
21 | 21 | ||
@@ -785,7 +785,7 @@ mips-sony-bsd|mips-sony-newsos4) | |||
785 | # Preauth crypto occasionally uses file descriptors for crypto offload | 785 | # Preauth crypto occasionally uses file descriptors for crypto offload |
786 | # and will crash if they cannot be opened. | 786 | # and will crash if they cannot be opened. |
787 | AC_DEFINE([SANDBOX_SKIP_RLIMIT_NOFILE], [1], | 787 | AC_DEFINE([SANDBOX_SKIP_RLIMIT_NOFILE], [1], |
788 | [define if setrlimit RLIMIT_NOFILE breaks things])], | 788 | [define if setrlimit RLIMIT_NOFILE breaks things]) |
789 | ;; | 789 | ;; |
790 | *-*-bsdi*) | 790 | *-*-bsdi*) |
791 | AC_DEFINE([SETEUID_BREAKS_SETUID]) | 791 | AC_DEFINE([SETEUID_BREAKS_SETUID]) |
@@ -1649,6 +1649,7 @@ AC_CHECK_FUNCS([ \ | |||
1649 | closefrom \ | 1649 | closefrom \ |
1650 | dirfd \ | 1650 | dirfd \ |
1651 | endgrent \ | 1651 | endgrent \ |
1652 | explicit_bzero \ | ||
1652 | fchmod \ | 1653 | fchmod \ |
1653 | fchown \ | 1654 | fchown \ |
1654 | freeaddrinfo \ | 1655 | freeaddrinfo \ |
@@ -2429,6 +2430,7 @@ AC_CHECK_FUNCS([ \ | |||
2429 | EVP_DigestFinal_ex \ | 2430 | EVP_DigestFinal_ex \ |
2430 | EVP_MD_CTX_init \ | 2431 | EVP_MD_CTX_init \ |
2431 | EVP_MD_CTX_cleanup \ | 2432 | EVP_MD_CTX_cleanup \ |
2433 | EVP_MD_CTX_copy_ex \ | ||
2432 | HMAC_CTX_init \ | 2434 | HMAC_CTX_init \ |
2433 | RSA_generate_key_ex \ | 2435 | RSA_generate_key_ex \ |
2434 | RSA_get_default_method \ | 2436 | RSA_get_default_method \ |
diff --git a/contrib/caldera/openssh.spec b/contrib/caldera/openssh.spec index 3c417bb8f..0061fe933 100644 --- a/contrib/caldera/openssh.spec +++ b/contrib/caldera/openssh.spec | |||
@@ -16,7 +16,7 @@ | |||
16 | 16 | ||
17 | #old cvs stuff. please update before use. may be deprecated. | 17 | #old cvs stuff. please update before use. may be deprecated. |
18 | %define use_stable 1 | 18 | %define use_stable 1 |
19 | %define version 6.5p1 | 19 | %define version 6.6p1 |
20 | %if %{use_stable} | 20 | %if %{use_stable} |
21 | %define cvs %{nil} | 21 | %define cvs %{nil} |
22 | %define release 1 | 22 | %define release 1 |
@@ -363,4 +363,4 @@ fi | |||
363 | * Mon Jan 01 1998 ... | 363 | * Mon Jan 01 1998 ... |
364 | Template Version: 1.31 | 364 | Template Version: 1.31 |
365 | 365 | ||
366 | $Id: openssh.spec,v 1.82 2014/01/16 07:51:10 djm Exp $ | 366 | $Id: openssh.spec,v 1.83 2014/02/27 23:03:55 djm Exp $ |
diff --git a/contrib/redhat/openssh.spec b/contrib/redhat/openssh.spec index d47cf3862..96401c6ee 100644 --- a/contrib/redhat/openssh.spec +++ b/contrib/redhat/openssh.spec | |||
@@ -1,4 +1,4 @@ | |||
1 | %define ver 6.5p1 | 1 | %define ver 6.6p1 |
2 | %define rel 1 | 2 | %define rel 1 |
3 | 3 | ||
4 | # OpenSSH privilege separation requires a user & group ID | 4 | # OpenSSH privilege separation requires a user & group ID |
diff --git a/contrib/suse/openssh.spec b/contrib/suse/openssh.spec index 6693fe2bc..0515d6d7c 100644 --- a/contrib/suse/openssh.spec +++ b/contrib/suse/openssh.spec | |||
@@ -13,7 +13,7 @@ | |||
13 | 13 | ||
14 | Summary: OpenSSH, a free Secure Shell (SSH) protocol implementation | 14 | Summary: OpenSSH, a free Secure Shell (SSH) protocol implementation |
15 | Name: openssh | 15 | Name: openssh |
16 | Version: 6.5p1 | 16 | Version: 6.6p1 |
17 | URL: http://www.openssh.com/ | 17 | URL: http://www.openssh.com/ |
18 | Release: 1 | 18 | Release: 1 |
19 | Source0: openssh-%{version}.tar.gz | 19 | Source0: openssh-%{version}.tar.gz |
diff --git a/digest-libc.c b/digest-libc.c new file mode 100644 index 000000000..1804b0698 --- /dev/null +++ b/digest-libc.c | |||
@@ -0,0 +1,238 @@ | |||
1 | /* $OpenBSD: digest-libc.c,v 1.2 2014/02/02 03:44:31 djm Exp $ */ | ||
2 | /* | ||
3 | * Copyright (c) 2013 Damien Miller <djm@mindrot.org> | ||
4 | * Copyright (c) 2014 Markus Friedl. All rights reserved. | ||
5 | * | ||
6 | * Permission to use, copy, modify, and distribute this software for any | ||
7 | * purpose with or without fee is hereby granted, provided that the above | ||
8 | * copyright notice and this permission notice appear in all copies. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
14 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
16 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
17 | */ | ||
18 | |||
19 | #include "includes.h" | ||
20 | |||
21 | #include <sys/types.h> | ||
22 | #include <limits.h> | ||
23 | #include <stdlib.h> | ||
24 | #include <string.h> | ||
25 | |||
26 | #include <md5.h> | ||
27 | #include <rmd160.h> | ||
28 | #include <sha1.h> | ||
29 | #include <sha2.h> | ||
30 | |||
31 | #include "buffer.h" | ||
32 | #include "digest.h" | ||
33 | |||
34 | typedef void md_init_fn(void *mdctx); | ||
35 | typedef void md_update_fn(void *mdctx, const u_int8_t *m, size_t mlen); | ||
36 | typedef void md_final_fn(u_int8_t[], void *mdctx); | ||
37 | |||
38 | struct ssh_digest_ctx { | ||
39 | int alg; | ||
40 | void *mdctx; | ||
41 | }; | ||
42 | |||
43 | struct ssh_digest { | ||
44 | int id; | ||
45 | const char *name; | ||
46 | size_t block_len; | ||
47 | size_t digest_len; | ||
48 | size_t ctx_len; | ||
49 | md_init_fn *md_init; | ||
50 | md_update_fn *md_update; | ||
51 | md_final_fn *md_final; | ||
52 | }; | ||
53 | |||
54 | /* NB. Indexed directly by algorithm number */ | ||
55 | const struct ssh_digest digests[SSH_DIGEST_MAX] = { | ||
56 | { | ||
57 | SSH_DIGEST_MD5, | ||
58 | "MD5", | ||
59 | MD5_BLOCK_LENGTH, | ||
60 | MD5_DIGEST_LENGTH, | ||
61 | sizeof(MD5_CTX), | ||
62 | (md_init_fn *) MD5Init, | ||
63 | (md_update_fn *) MD5Update, | ||
64 | (md_final_fn *) MD5Final | ||
65 | }, | ||
66 | { | ||
67 | SSH_DIGEST_RIPEMD160, | ||
68 | "RIPEMD160", | ||
69 | RMD160_BLOCK_LENGTH, | ||
70 | RMD160_DIGEST_LENGTH, | ||
71 | sizeof(RMD160_CTX), | ||
72 | (md_init_fn *) RMD160Init, | ||
73 | (md_update_fn *) RMD160Update, | ||
74 | (md_final_fn *) RMD160Final | ||
75 | }, | ||
76 | { | ||
77 | SSH_DIGEST_SHA1, | ||
78 | "SHA1", | ||
79 | SHA1_BLOCK_LENGTH, | ||
80 | SHA1_DIGEST_LENGTH, | ||
81 | sizeof(SHA1_CTX), | ||
82 | (md_init_fn *) SHA1Init, | ||
83 | (md_update_fn *) SHA1Update, | ||
84 | (md_final_fn *) SHA1Final | ||
85 | }, | ||
86 | { | ||
87 | SSH_DIGEST_SHA256, | ||
88 | "SHA256", | ||
89 | SHA256_BLOCK_LENGTH, | ||
90 | SHA256_DIGEST_LENGTH, | ||
91 | sizeof(SHA2_CTX), | ||
92 | (md_init_fn *) SHA256Init, | ||
93 | (md_update_fn *) SHA256Update, | ||
94 | (md_final_fn *) SHA256Final | ||
95 | }, | ||
96 | { | ||
97 | SSH_DIGEST_SHA384, | ||
98 | "SHA384", | ||
99 | SHA384_BLOCK_LENGTH, | ||
100 | SHA384_DIGEST_LENGTH, | ||
101 | sizeof(SHA2_CTX), | ||
102 | (md_init_fn *) SHA384Init, | ||
103 | (md_update_fn *) SHA384Update, | ||
104 | (md_final_fn *) SHA384Final | ||
105 | }, | ||
106 | { | ||
107 | SSH_DIGEST_SHA512, | ||
108 | "SHA512", | ||
109 | SHA512_BLOCK_LENGTH, | ||
110 | SHA512_DIGEST_LENGTH, | ||
111 | sizeof(SHA2_CTX), | ||
112 | (md_init_fn *) SHA512Init, | ||
113 | (md_update_fn *) SHA512Update, | ||
114 | (md_final_fn *) SHA512Final | ||
115 | } | ||
116 | }; | ||
117 | |||
118 | static const struct ssh_digest * | ||
119 | ssh_digest_by_alg(int alg) | ||
120 | { | ||
121 | if (alg < 0 || alg >= SSH_DIGEST_MAX) | ||
122 | return NULL; | ||
123 | if (digests[alg].id != alg) /* sanity */ | ||
124 | return NULL; | ||
125 | return &(digests[alg]); | ||
126 | } | ||
127 | |||
128 | size_t | ||
129 | ssh_digest_bytes(int alg) | ||
130 | { | ||
131 | const struct ssh_digest *digest = ssh_digest_by_alg(alg); | ||
132 | |||
133 | return digest == NULL ? 0 : digest->digest_len; | ||
134 | } | ||
135 | |||
136 | size_t | ||
137 | ssh_digest_blocksize(struct ssh_digest_ctx *ctx) | ||
138 | { | ||
139 | const struct ssh_digest *digest = ssh_digest_by_alg(ctx->alg); | ||
140 | |||
141 | return digest == NULL ? 0 : digest->block_len; | ||
142 | } | ||
143 | |||
144 | struct ssh_digest_ctx * | ||
145 | ssh_digest_start(int alg) | ||
146 | { | ||
147 | const struct ssh_digest *digest = ssh_digest_by_alg(alg); | ||
148 | struct ssh_digest_ctx *ret; | ||
149 | |||
150 | if (digest == NULL || (ret = calloc(1, sizeof(ret))) == NULL) | ||
151 | return NULL; | ||
152 | if ((ret->mdctx = calloc(1, digest->ctx_len)) == NULL) { | ||
153 | free(ret); | ||
154 | return NULL; | ||
155 | } | ||
156 | ret->alg = alg; | ||
157 | digest->md_init(ret->mdctx); | ||
158 | return ret; | ||
159 | } | ||
160 | |||
161 | int | ||
162 | ssh_digest_copy_state(struct ssh_digest_ctx *from, struct ssh_digest_ctx *to) | ||
163 | { | ||
164 | const struct ssh_digest *digest = ssh_digest_by_alg(from->alg); | ||
165 | |||
166 | if (digest == NULL || from->alg != to->alg) | ||
167 | return -1; | ||
168 | memcpy(to->mdctx, from->mdctx, digest->ctx_len); | ||
169 | return 0; | ||
170 | } | ||
171 | |||
172 | int | ||
173 | ssh_digest_update(struct ssh_digest_ctx *ctx, const void *m, size_t mlen) | ||
174 | { | ||
175 | const struct ssh_digest *digest = ssh_digest_by_alg(ctx->alg); | ||
176 | |||
177 | if (digest == NULL) | ||
178 | return -1; | ||
179 | digest->md_update(ctx->mdctx, m, mlen); | ||
180 | return 0; | ||
181 | } | ||
182 | |||
183 | int | ||
184 | ssh_digest_update_buffer(struct ssh_digest_ctx *ctx, const Buffer *b) | ||
185 | { | ||
186 | return ssh_digest_update(ctx, buffer_ptr(b), buffer_len(b)); | ||
187 | } | ||
188 | |||
189 | int | ||
190 | ssh_digest_final(struct ssh_digest_ctx *ctx, u_char *d, size_t dlen) | ||
191 | { | ||
192 | const struct ssh_digest *digest = ssh_digest_by_alg(ctx->alg); | ||
193 | |||
194 | if (digest == NULL) | ||
195 | return -1; | ||
196 | if (dlen > UINT_MAX) | ||
197 | return -1; | ||
198 | if (dlen < digest->digest_len) /* No truncation allowed */ | ||
199 | return -1; | ||
200 | digest->md_final(d, ctx->mdctx); | ||
201 | return 0; | ||
202 | } | ||
203 | |||
204 | void | ||
205 | ssh_digest_free(struct ssh_digest_ctx *ctx) | ||
206 | { | ||
207 | const struct ssh_digest *digest; | ||
208 | |||
209 | if (ctx != NULL) { | ||
210 | digest = ssh_digest_by_alg(ctx->alg); | ||
211 | if (digest) { | ||
212 | explicit_bzero(ctx->mdctx, digest->ctx_len); | ||
213 | free(ctx->mdctx); | ||
214 | explicit_bzero(ctx, sizeof(*ctx)); | ||
215 | free(ctx); | ||
216 | } | ||
217 | } | ||
218 | } | ||
219 | |||
220 | int | ||
221 | ssh_digest_memory(int alg, const void *m, size_t mlen, u_char *d, size_t dlen) | ||
222 | { | ||
223 | struct ssh_digest_ctx *ctx = ssh_digest_start(alg); | ||
224 | |||
225 | if (ctx == NULL) | ||
226 | return -1; | ||
227 | if (ssh_digest_update(ctx, m, mlen) != 0 || | ||
228 | ssh_digest_final(ctx, d, dlen) != 0) | ||
229 | return -1; | ||
230 | ssh_digest_free(ctx); | ||
231 | return 0; | ||
232 | } | ||
233 | |||
234 | int | ||
235 | ssh_digest_buffer(int alg, const Buffer *b, u_char *d, size_t dlen) | ||
236 | { | ||
237 | return ssh_digest_memory(alg, buffer_ptr(b), buffer_len(b), d, dlen); | ||
238 | } | ||
diff --git a/digest.c b/digest-openssl.c index a221819eb..863d37d03 100644 --- a/digest.c +++ b/digest-openssl.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: digest.c,v 1.3 2014/01/20 00:08:48 djm Exp $ */ | 1 | /* $OpenBSD: digest-openssl.c,v 1.2 2014/02/02 03:44:31 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2013 Damien Miller <djm@mindrot.org> | 3 | * Copyright (c) 2013 Damien Miller <djm@mindrot.org> |
4 | * | 4 | * |
@@ -72,6 +72,12 @@ ssh_digest_bytes(int alg) | |||
72 | return digest == NULL ? 0 : digest->digest_len; | 72 | return digest == NULL ? 0 : digest->digest_len; |
73 | } | 73 | } |
74 | 74 | ||
75 | size_t | ||
76 | ssh_digest_blocksize(struct ssh_digest_ctx *ctx) | ||
77 | { | ||
78 | return EVP_MD_CTX_block_size(&ctx->mdctx); | ||
79 | } | ||
80 | |||
75 | struct ssh_digest_ctx * | 81 | struct ssh_digest_ctx * |
76 | ssh_digest_start(int alg) | 82 | ssh_digest_start(int alg) |
77 | { | 83 | { |
@@ -90,6 +96,15 @@ ssh_digest_start(int alg) | |||
90 | } | 96 | } |
91 | 97 | ||
92 | int | 98 | int |
99 | ssh_digest_copy_state(struct ssh_digest_ctx *from, struct ssh_digest_ctx *to) | ||
100 | { | ||
101 | /* we have bcopy-style order while openssl has memcpy-style */ | ||
102 | if (!EVP_MD_CTX_copy_ex(&to->mdctx, &from->mdctx)) | ||
103 | return -1; | ||
104 | return 0; | ||
105 | } | ||
106 | |||
107 | int | ||
93 | ssh_digest_update(struct ssh_digest_ctx *ctx, const void *m, size_t mlen) | 108 | ssh_digest_update(struct ssh_digest_ctx *ctx, const void *m, size_t mlen) |
94 | { | 109 | { |
95 | if (EVP_DigestUpdate(&ctx->mdctx, m, mlen) != 1) | 110 | if (EVP_DigestUpdate(&ctx->mdctx, m, mlen) != 1) |
@@ -123,9 +138,11 @@ ssh_digest_final(struct ssh_digest_ctx *ctx, u_char *d, size_t dlen) | |||
123 | void | 138 | void |
124 | ssh_digest_free(struct ssh_digest_ctx *ctx) | 139 | ssh_digest_free(struct ssh_digest_ctx *ctx) |
125 | { | 140 | { |
126 | EVP_MD_CTX_cleanup(&ctx->mdctx); | 141 | if (ctx != NULL) { |
127 | memset(ctx, 0, sizeof(*ctx)); | 142 | EVP_MD_CTX_cleanup(&ctx->mdctx); |
128 | free(ctx); | 143 | explicit_bzero(ctx, sizeof(*ctx)); |
144 | free(ctx); | ||
145 | } | ||
129 | } | 146 | } |
130 | 147 | ||
131 | int | 148 | int |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: digest.h,v 1.1 2014/01/09 23:20:00 djm Exp $ */ | 1 | /* $OpenBSD: digest.h,v 1.2 2014/01/27 18:58:14 markus Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2013 Damien Miller <djm@mindrot.org> | 3 | * Copyright (c) 2013 Damien Miller <djm@mindrot.org> |
4 | * | 4 | * |
@@ -30,9 +30,18 @@ | |||
30 | #define SSH_DIGEST_SHA512 5 | 30 | #define SSH_DIGEST_SHA512 5 |
31 | #define SSH_DIGEST_MAX 6 | 31 | #define SSH_DIGEST_MAX 6 |
32 | 32 | ||
33 | struct ssh_digest_ctx; | ||
34 | |||
33 | /* Returns the algorithm's digest length in bytes or 0 for invalid algorithm */ | 35 | /* Returns the algorithm's digest length in bytes or 0 for invalid algorithm */ |
34 | size_t ssh_digest_bytes(int alg); | 36 | size_t ssh_digest_bytes(int alg); |
35 | 37 | ||
38 | /* Returns the block size of the digest, e.g. for implementing HMAC */ | ||
39 | size_t ssh_digest_blocksize(struct ssh_digest_ctx *ctx); | ||
40 | |||
41 | /* Copies internal state of digest of 'from' to 'to' */ | ||
42 | int ssh_digest_copy_state(struct ssh_digest_ctx *from, | ||
43 | struct ssh_digest_ctx *to); | ||
44 | |||
36 | /* One-shot API */ | 45 | /* One-shot API */ |
37 | int ssh_digest_memory(int alg, const void *m, size_t mlen, | 46 | int ssh_digest_memory(int alg, const void *m, size_t mlen, |
38 | u_char *d, size_t dlen) | 47 | 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) | |||
42 | __attribute__((__bounded__(__buffer__, 3, 4))); | 51 | __attribute__((__bounded__(__buffer__, 3, 4))); |
43 | 52 | ||
44 | /* Update API */ | 53 | /* Update API */ |
45 | struct ssh_digest_ctx; | ||
46 | struct ssh_digest_ctx *ssh_digest_start(int alg); | 54 | struct ssh_digest_ctx *ssh_digest_start(int alg); |
47 | int ssh_digest_update(struct ssh_digest_ctx *ctx, const void *m, size_t mlen) | 55 | int ssh_digest_update(struct ssh_digest_ctx *ctx, const void *m, size_t mlen) |
48 | __attribute__((__bounded__(__buffer__, 2, 3))); | 56 | __attribute__((__bounded__(__buffer__, 2, 3))); |
diff --git a/gss-serv.c b/gss-serv.c index 95348e251..e61b37bec 100644 --- a/gss-serv.c +++ b/gss-serv.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: gss-serv.c,v 1.24 2013/07/20 01:55:13 djm Exp $ */ | 1 | /* $OpenBSD: gss-serv.c,v 1.26 2014/02/26 20:28:44 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. | 4 | * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. |
@@ -66,6 +66,25 @@ ssh_gssapi_mech* supported_mechs[]= { | |||
66 | &gssapi_null_mech, | 66 | &gssapi_null_mech, |
67 | }; | 67 | }; |
68 | 68 | ||
69 | /* | ||
70 | * ssh_gssapi_supported_oids() can cause sandbox violations, so prepare the | ||
71 | * list of supported mechanisms before privsep is set up. | ||
72 | */ | ||
73 | static gss_OID_set supported_oids; | ||
74 | |||
75 | void | ||
76 | ssh_gssapi_prepare_supported_oids(void) | ||
77 | { | ||
78 | ssh_gssapi_supported_oids(&supported_oids); | ||
79 | } | ||
80 | |||
81 | OM_uint32 | ||
82 | ssh_gssapi_test_oid_supported(OM_uint32 *ms, gss_OID member, int *present) | ||
83 | { | ||
84 | if (supported_oids == NULL) | ||
85 | ssh_gssapi_prepare_supported_oids(); | ||
86 | return gss_test_oid_set_member(ms, member, supported_oids, present); | ||
87 | } | ||
69 | 88 | ||
70 | /* | 89 | /* |
71 | * Acquire credentials for a server running on the current host. | 90 | * Acquire credentials for a server running on the current host. |
@@ -346,7 +365,8 @@ ssh_gssapi_userok(char *user) | |||
346 | gss_release_buffer(&lmin, &gssapi_client.displayname); | 365 | gss_release_buffer(&lmin, &gssapi_client.displayname); |
347 | gss_release_buffer(&lmin, &gssapi_client.exportedname); | 366 | gss_release_buffer(&lmin, &gssapi_client.exportedname); |
348 | gss_release_cred(&lmin, &gssapi_client.creds); | 367 | gss_release_cred(&lmin, &gssapi_client.creds); |
349 | memset(&gssapi_client, 0, sizeof(ssh_gssapi_client)); | 368 | explicit_bzero(&gssapi_client, |
369 | sizeof(ssh_gssapi_client)); | ||
350 | return 0; | 370 | return 0; |
351 | } | 371 | } |
352 | else | 372 | else |
@@ -0,0 +1,197 @@ | |||
1 | /* $OpenBSD: hmac.c,v 1.10 2014/01/31 16:39:19 tedu Exp $ */ | ||
2 | /* | ||
3 | * Copyright (c) 2014 Markus Friedl. All rights reserved. | ||
4 | * | ||
5 | * Permission to use, copy, modify, and distribute this software for any | ||
6 | * purpose with or without fee is hereby granted, provided that the above | ||
7 | * copyright notice and this permission notice appear in all copies. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
10 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
11 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
12 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
13 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
16 | */ | ||
17 | |||
18 | #include "includes.h" | ||
19 | |||
20 | #include <sys/types.h> | ||
21 | #include <string.h> | ||
22 | |||
23 | #include "buffer.h" | ||
24 | #include "digest.h" | ||
25 | #include "hmac.h" | ||
26 | |||
27 | struct ssh_hmac_ctx { | ||
28 | int alg; | ||
29 | struct ssh_digest_ctx *ictx; | ||
30 | struct ssh_digest_ctx *octx; | ||
31 | struct ssh_digest_ctx *digest; | ||
32 | u_char *buf; | ||
33 | size_t buf_len; | ||
34 | }; | ||
35 | |||
36 | size_t | ||
37 | ssh_hmac_bytes(int alg) | ||
38 | { | ||
39 | return ssh_digest_bytes(alg); | ||
40 | } | ||
41 | |||
42 | struct ssh_hmac_ctx * | ||
43 | ssh_hmac_start(int alg) | ||
44 | { | ||
45 | struct ssh_hmac_ctx *ret; | ||
46 | |||
47 | if ((ret = calloc(1, sizeof(*ret))) == NULL) | ||
48 | return NULL; | ||
49 | ret->alg = alg; | ||
50 | if ((ret->ictx = ssh_digest_start(alg)) == NULL || | ||
51 | (ret->octx = ssh_digest_start(alg)) == NULL || | ||
52 | (ret->digest = ssh_digest_start(alg)) == NULL) | ||
53 | goto fail; | ||
54 | ret->buf_len = ssh_digest_blocksize(ret->ictx); | ||
55 | if ((ret->buf = calloc(1, ret->buf_len)) == NULL) | ||
56 | goto fail; | ||
57 | return ret; | ||
58 | fail: | ||
59 | ssh_hmac_free(ret); | ||
60 | return NULL; | ||
61 | } | ||
62 | |||
63 | int | ||
64 | ssh_hmac_init(struct ssh_hmac_ctx *ctx, const void *key, size_t klen) | ||
65 | { | ||
66 | size_t i; | ||
67 | |||
68 | /* reset ictx and octx if no is key given */ | ||
69 | if (key != NULL) { | ||
70 | /* truncate long keys */ | ||
71 | if (klen <= ctx->buf_len) | ||
72 | memcpy(ctx->buf, key, klen); | ||
73 | else if (ssh_digest_memory(ctx->alg, key, klen, ctx->buf, | ||
74 | ctx->buf_len) < 0) | ||
75 | return -1; | ||
76 | for (i = 0; i < ctx->buf_len; i++) | ||
77 | ctx->buf[i] ^= 0x36; | ||
78 | if (ssh_digest_update(ctx->ictx, ctx->buf, ctx->buf_len) < 0) | ||
79 | return -1; | ||
80 | for (i = 0; i < ctx->buf_len; i++) | ||
81 | ctx->buf[i] ^= 0x36 ^ 0x5c; | ||
82 | if (ssh_digest_update(ctx->octx, ctx->buf, ctx->buf_len) < 0) | ||
83 | return -1; | ||
84 | explicit_bzero(ctx->buf, ctx->buf_len); | ||
85 | } | ||
86 | /* start with ictx */ | ||
87 | if (ssh_digest_copy_state(ctx->ictx, ctx->digest) < 0) | ||
88 | return -1; | ||
89 | return 0; | ||
90 | } | ||
91 | |||
92 | int | ||
93 | ssh_hmac_update(struct ssh_hmac_ctx *ctx, const void *m, size_t mlen) | ||
94 | { | ||
95 | return ssh_digest_update(ctx->digest, m, mlen); | ||
96 | } | ||
97 | |||
98 | int | ||
99 | ssh_hmac_update_buffer(struct ssh_hmac_ctx *ctx, const Buffer *b) | ||
100 | { | ||
101 | return ssh_digest_update_buffer(ctx->digest, b); | ||
102 | } | ||
103 | |||
104 | int | ||
105 | ssh_hmac_final(struct ssh_hmac_ctx *ctx, u_char *d, size_t dlen) | ||
106 | { | ||
107 | size_t len; | ||
108 | |||
109 | len = ssh_digest_bytes(ctx->alg); | ||
110 | if (dlen < len || | ||
111 | ssh_digest_final(ctx->digest, ctx->buf, len)) | ||
112 | return -1; | ||
113 | /* switch to octx */ | ||
114 | if (ssh_digest_copy_state(ctx->octx, ctx->digest) < 0 || | ||
115 | ssh_digest_update(ctx->digest, ctx->buf, len) < 0 || | ||
116 | ssh_digest_final(ctx->digest, d, dlen) < 0) | ||
117 | return -1; | ||
118 | return 0; | ||
119 | } | ||
120 | |||
121 | void | ||
122 | ssh_hmac_free(struct ssh_hmac_ctx *ctx) | ||
123 | { | ||
124 | if (ctx != NULL) { | ||
125 | ssh_digest_free(ctx->ictx); | ||
126 | ssh_digest_free(ctx->octx); | ||
127 | ssh_digest_free(ctx->digest); | ||
128 | if (ctx->buf) { | ||
129 | explicit_bzero(ctx->buf, ctx->buf_len); | ||
130 | free(ctx->buf); | ||
131 | } | ||
132 | explicit_bzero(ctx, sizeof(*ctx)); | ||
133 | free(ctx); | ||
134 | } | ||
135 | } | ||
136 | |||
137 | #ifdef TEST | ||
138 | |||
139 | /* cc -DTEST hmac.c digest.c buffer.c cleanup.c fatal.c log.c xmalloc.c -lcrypto */ | ||
140 | static void | ||
141 | hmac_test(void *key, size_t klen, void *m, size_t mlen, u_char *e, size_t elen) | ||
142 | { | ||
143 | struct ssh_hmac_ctx *ctx; | ||
144 | size_t i; | ||
145 | u_char digest[16]; | ||
146 | |||
147 | if ((ctx = ssh_hmac_start(SSH_DIGEST_MD5)) == NULL) | ||
148 | printf("ssh_hmac_start failed"); | ||
149 | if (ssh_hmac_init(ctx, key, klen) < 0 || | ||
150 | ssh_hmac_update(ctx, m, mlen) < 0 || | ||
151 | ssh_hmac_final(ctx, digest, sizeof(digest)) < 0) | ||
152 | printf("ssh_hmac_xxx failed"); | ||
153 | ssh_hmac_free(ctx); | ||
154 | |||
155 | if (memcmp(e, digest, elen)) { | ||
156 | for (i = 0; i < elen; i++) | ||
157 | printf("[%zd] %2.2x %2.2x\n", i, e[i], digest[i]); | ||
158 | printf("mismatch\n"); | ||
159 | } else | ||
160 | printf("ok\n"); | ||
161 | } | ||
162 | |||
163 | int | ||
164 | main(int argc, char **argv) | ||
165 | { | ||
166 | /* try test vectors from RFC 2104 */ | ||
167 | |||
168 | u_char key1[16] = { | ||
169 | 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, | ||
170 | 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb }; | ||
171 | u_char *data1 = "Hi There"; | ||
172 | u_char dig1[16] = { | ||
173 | 0x92, 0x94, 0x72, 0x7a, 0x36, 0x38, 0xbb, 0x1c, | ||
174 | 0x13, 0xf4, 0x8e, 0xf8, 0x15, 0x8b, 0xfc, 0x9d }; | ||
175 | |||
176 | u_char *key2 = "Jefe"; | ||
177 | u_char *data2 = "what do ya want for nothing?"; | ||
178 | u_char dig2[16] = { | ||
179 | 0x75, 0x0c, 0x78, 0x3e, 0x6a, 0xb0, 0xb5, 0x03, | ||
180 | 0xea, 0xa8, 0x6e, 0x31, 0x0a, 0x5d, 0xb7, 0x38 }; | ||
181 | |||
182 | u_char key3[16]; | ||
183 | u_char data3[50]; | ||
184 | u_char dig3[16] = { | ||
185 | 0x56, 0xbe, 0x34, 0x52, 0x1d, 0x14, 0x4c, 0x88, | ||
186 | 0xdb, 0xb8, 0xc7, 0x33, 0xf0, 0xe8, 0xb3, 0xf6 }; | ||
187 | memset(key3, 0xaa, sizeof(key3)); | ||
188 | memset(data3, 0xdd, sizeof(data3)); | ||
189 | |||
190 | hmac_test(key1, sizeof(key1), data1, strlen(data1), dig1, sizeof(dig1)); | ||
191 | hmac_test(key2, strlen(key2), data2, strlen(data2), dig2, sizeof(dig2)); | ||
192 | hmac_test(key3, sizeof(key3), data3, sizeof(data3), dig3, sizeof(dig3)); | ||
193 | |||
194 | return 0; | ||
195 | } | ||
196 | |||
197 | #endif | ||
@@ -0,0 +1,37 @@ | |||
1 | /* $OpenBSD: hmac.h,v 1.6 2014/01/27 18:58:14 markus Exp $ */ | ||
2 | /* | ||
3 | * Copyright (c) 2014 Markus Friedl. All rights reserved. | ||
4 | * | ||
5 | * Permission to use, copy, modify, and distribute this software for any | ||
6 | * purpose with or without fee is hereby granted, provided that the above | ||
7 | * copyright notice and this permission notice appear in all copies. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
10 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
11 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
12 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
13 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
16 | */ | ||
17 | |||
18 | #ifndef _HMAC_H | ||
19 | #define _HMAC_H | ||
20 | |||
21 | /* Returns the algorithm's digest length in bytes or 0 for invalid algorithm */ | ||
22 | size_t ssh_hmac_bytes(int alg); | ||
23 | |||
24 | struct ssh_hmac_ctx; | ||
25 | struct ssh_hmac_ctx *ssh_hmac_start(int alg); | ||
26 | |||
27 | /* Sets the state of the HMAC or resets the state if key == NULL */ | ||
28 | int ssh_hmac_init(struct ssh_hmac_ctx *ctx, const void *key, size_t klen) | ||
29 | __attribute__((__bounded__(__buffer__, 2, 3))); | ||
30 | int ssh_hmac_update(struct ssh_hmac_ctx *ctx, const void *m, size_t mlen) | ||
31 | __attribute__((__bounded__(__buffer__, 2, 3))); | ||
32 | int ssh_hmac_update_buffer(struct ssh_hmac_ctx *ctx, const Buffer *b); | ||
33 | int ssh_hmac_final(struct ssh_hmac_ctx *ctx, u_char *d, size_t dlen) | ||
34 | __attribute__((__bounded__(__buffer__, 2, 3))); | ||
35 | void ssh_hmac_free(struct ssh_hmac_ctx *ctx); | ||
36 | |||
37 | #endif /* _HMAC_H */ | ||
diff --git a/hostfile.c b/hostfile.c index 2778fb5df..8bc9540b7 100644 --- a/hostfile.c +++ b/hostfile.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: hostfile.c,v 1.53 2014/01/09 23:20:00 djm Exp $ */ | 1 | /* $OpenBSD: hostfile.c,v 1.55 2014/01/31 16:39:19 tedu Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -42,9 +42,6 @@ | |||
42 | 42 | ||
43 | #include <netinet/in.h> | 43 | #include <netinet/in.h> |
44 | 44 | ||
45 | #include <openssl/hmac.h> | ||
46 | #include <openssl/sha.h> | ||
47 | |||
48 | #include <resolv.h> | 45 | #include <resolv.h> |
49 | #include <stdarg.h> | 46 | #include <stdarg.h> |
50 | #include <stdio.h> | 47 | #include <stdio.h> |
@@ -58,6 +55,7 @@ | |||
58 | #include "log.h" | 55 | #include "log.h" |
59 | #include "misc.h" | 56 | #include "misc.h" |
60 | #include "digest.h" | 57 | #include "digest.h" |
58 | #include "hmac.h" | ||
61 | 59 | ||
62 | struct hostkeys { | 60 | struct hostkeys { |
63 | struct hostkey_entry *entries; | 61 | struct hostkey_entry *entries; |
@@ -102,9 +100,9 @@ extract_salt(const char *s, u_int l, u_char *salt, size_t salt_len) | |||
102 | debug2("extract_salt: salt decode error"); | 100 | debug2("extract_salt: salt decode error"); |
103 | return (-1); | 101 | return (-1); |
104 | } | 102 | } |
105 | if (ret != SHA_DIGEST_LENGTH) { | 103 | if (ret != (int)ssh_hmac_bytes(SSH_DIGEST_SHA1)) { |
106 | debug2("extract_salt: expected salt len %d, got %d", | 104 | debug2("extract_salt: expected salt len %zd, got %d", |
107 | SHA_DIGEST_LENGTH, ret); | 105 | ssh_hmac_bytes(SSH_DIGEST_SHA1), ret); |
108 | return (-1); | 106 | return (-1); |
109 | } | 107 | } |
110 | 108 | ||
@@ -114,14 +112,13 @@ extract_salt(const char *s, u_int l, u_char *salt, size_t salt_len) | |||
114 | char * | 112 | char * |
115 | host_hash(const char *host, const char *name_from_hostfile, u_int src_len) | 113 | host_hash(const char *host, const char *name_from_hostfile, u_int src_len) |
116 | { | 114 | { |
117 | const EVP_MD *md = EVP_sha1(); | 115 | struct ssh_hmac_ctx *ctx; |
118 | HMAC_CTX mac_ctx; | ||
119 | u_char salt[256], result[256]; | 116 | u_char salt[256], result[256]; |
120 | char uu_salt[512], uu_result[512]; | 117 | char uu_salt[512], uu_result[512]; |
121 | static char encoded[1024]; | 118 | static char encoded[1024]; |
122 | u_int i, len; | 119 | u_int i, len; |
123 | 120 | ||
124 | len = EVP_MD_size(md); | 121 | len = ssh_digest_bytes(SSH_DIGEST_SHA1); |
125 | 122 | ||
126 | if (name_from_hostfile == NULL) { | 123 | if (name_from_hostfile == NULL) { |
127 | /* Create new salt */ | 124 | /* Create new salt */ |
@@ -134,14 +131,16 @@ host_hash(const char *host, const char *name_from_hostfile, u_int src_len) | |||
134 | return (NULL); | 131 | return (NULL); |
135 | } | 132 | } |
136 | 133 | ||
137 | HMAC_Init(&mac_ctx, salt, len, md); | 134 | if ((ctx = ssh_hmac_start(SSH_DIGEST_SHA1)) == NULL || |
138 | HMAC_Update(&mac_ctx, (u_char *)host, strlen(host)); | 135 | ssh_hmac_init(ctx, salt, len) < 0 || |
139 | HMAC_Final(&mac_ctx, result, NULL); | 136 | ssh_hmac_update(ctx, host, strlen(host)) < 0 || |
140 | HMAC_cleanup(&mac_ctx); | 137 | ssh_hmac_final(ctx, result, sizeof(result))) |
138 | fatal("%s: ssh_hmac failed", __func__); | ||
139 | ssh_hmac_free(ctx); | ||
141 | 140 | ||
142 | if (__b64_ntop(salt, len, uu_salt, sizeof(uu_salt)) == -1 || | 141 | if (__b64_ntop(salt, len, uu_salt, sizeof(uu_salt)) == -1 || |
143 | __b64_ntop(result, len, uu_result, sizeof(uu_result)) == -1) | 142 | __b64_ntop(result, len, uu_result, sizeof(uu_result)) == -1) |
144 | fatal("host_hash: __b64_ntop failed"); | 143 | fatal("%s: __b64_ntop failed", __func__); |
145 | 144 | ||
146 | snprintf(encoded, sizeof(encoded), "%s%s%c%s", HASH_MAGIC, uu_salt, | 145 | snprintf(encoded, sizeof(encoded), "%s%s%c%s", HASH_MAGIC, uu_salt, |
147 | HASH_DELIM, uu_result); | 146 | HASH_DELIM, uu_result); |
@@ -334,10 +333,10 @@ free_hostkeys(struct hostkeys *hostkeys) | |||
334 | free(hostkeys->entries[i].host); | 333 | free(hostkeys->entries[i].host); |
335 | free(hostkeys->entries[i].file); | 334 | free(hostkeys->entries[i].file); |
336 | key_free(hostkeys->entries[i].key); | 335 | key_free(hostkeys->entries[i].key); |
337 | bzero(hostkeys->entries + i, sizeof(*hostkeys->entries)); | 336 | explicit_bzero(hostkeys->entries + i, sizeof(*hostkeys->entries)); |
338 | } | 337 | } |
339 | free(hostkeys->entries); | 338 | free(hostkeys->entries); |
340 | bzero(hostkeys, sizeof(*hostkeys)); | 339 | explicit_bzero(hostkeys, sizeof(*hostkeys)); |
341 | free(hostkeys); | 340 | free(hostkeys); |
342 | } | 341 | } |
343 | 342 | ||
diff --git a/jpake.c b/jpake.c deleted file mode 100644 index 3dd87916a..000000000 --- a/jpake.c +++ /dev/null | |||
@@ -1,456 +0,0 @@ | |||
1 | /* $OpenBSD: jpake.c,v 1.8 2013/05/17 00:13:13 djm Exp $ */ | ||
2 | /* | ||
3 | * Copyright (c) 2008 Damien Miller. All rights reserved. | ||
4 | * | ||
5 | * Permission to use, copy, modify, and distribute this software for any | ||
6 | * purpose with or without fee is hereby granted, provided that the above | ||
7 | * copyright notice and this permission notice appear in all copies. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
10 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
11 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
12 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
13 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
16 | */ | ||
17 | |||
18 | /* | ||
19 | * Shared components of zero-knowledge password auth using J-PAKE protocol | ||
20 | * as described in: | ||
21 | * | ||
22 | * F. Hao, P. Ryan, "Password Authenticated Key Exchange by Juggling", | ||
23 | * 16th Workshop on Security Protocols, Cambridge, April 2008 | ||
24 | * | ||
25 | * http://grouper.ieee.org/groups/1363/Research/contributions/hao-ryan-2008.pdf | ||
26 | */ | ||
27 | |||
28 | #include "includes.h" | ||
29 | |||
30 | #include <sys/types.h> | ||
31 | |||
32 | #include <stdio.h> | ||
33 | #include <string.h> | ||
34 | #include <stdarg.h> | ||
35 | |||
36 | #include <openssl/bn.h> | ||
37 | #include <openssl/evp.h> | ||
38 | |||
39 | #include "xmalloc.h" | ||
40 | #include "ssh2.h" | ||
41 | #include "key.h" | ||
42 | #include "hostfile.h" | ||
43 | #include "auth.h" | ||
44 | #include "buffer.h" | ||
45 | #include "packet.h" | ||
46 | #include "dispatch.h" | ||
47 | #include "log.h" | ||
48 | #include "misc.h" | ||
49 | |||
50 | #include "jpake.h" | ||
51 | #include "schnorr.h" | ||
52 | |||
53 | #ifdef JPAKE | ||
54 | |||
55 | /* RFC3526 group 5, 1536 bits */ | ||
56 | #define JPAKE_GROUP_G "2" | ||
57 | #define JPAKE_GROUP_P \ | ||
58 | "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74" \ | ||
59 | "020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437" \ | ||
60 | "4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" \ | ||
61 | "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05" \ | ||
62 | "98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB" \ | ||
63 | "9ED529077096966D670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF" | ||
64 | |||
65 | struct modp_group * | ||
66 | jpake_default_group(void) | ||
67 | { | ||
68 | return modp_group_from_g_and_safe_p(JPAKE_GROUP_G, JPAKE_GROUP_P); | ||
69 | } | ||
70 | |||
71 | struct jpake_ctx * | ||
72 | jpake_new(void) | ||
73 | { | ||
74 | struct jpake_ctx *ret; | ||
75 | |||
76 | ret = xcalloc(1, sizeof(*ret)); | ||
77 | |||
78 | ret->grp = jpake_default_group(); | ||
79 | |||
80 | ret->s = ret->k = NULL; | ||
81 | ret->x1 = ret->x2 = ret->x3 = ret->x4 = NULL; | ||
82 | ret->g_x1 = ret->g_x2 = ret->g_x3 = ret->g_x4 = NULL; | ||
83 | ret->a = ret->b = NULL; | ||
84 | |||
85 | ret->client_id = ret->server_id = NULL; | ||
86 | ret->h_k_cid_sessid = ret->h_k_sid_sessid = NULL; | ||
87 | |||
88 | debug3("%s: alloc %p", __func__, ret); | ||
89 | |||
90 | return ret; | ||
91 | } | ||
92 | |||
93 | void | ||
94 | jpake_free(struct jpake_ctx *pctx) | ||
95 | { | ||
96 | debug3("%s: free %p", __func__, pctx); | ||
97 | |||
98 | #define JPAKE_BN_CLEAR_FREE(v) \ | ||
99 | do { \ | ||
100 | if ((v) != NULL) { \ | ||
101 | BN_clear_free(v); \ | ||
102 | (v) = NULL; \ | ||
103 | } \ | ||
104 | } while (0) | ||
105 | #define JPAKE_BUF_CLEAR_FREE(v, l) \ | ||
106 | do { \ | ||
107 | if ((v) != NULL) { \ | ||
108 | bzero((v), (l)); \ | ||
109 | free(v); \ | ||
110 | (v) = NULL; \ | ||
111 | (l) = 0; \ | ||
112 | } \ | ||
113 | } while (0) | ||
114 | |||
115 | JPAKE_BN_CLEAR_FREE(pctx->s); | ||
116 | JPAKE_BN_CLEAR_FREE(pctx->k); | ||
117 | JPAKE_BN_CLEAR_FREE(pctx->x1); | ||
118 | JPAKE_BN_CLEAR_FREE(pctx->x2); | ||
119 | JPAKE_BN_CLEAR_FREE(pctx->x3); | ||
120 | JPAKE_BN_CLEAR_FREE(pctx->x4); | ||
121 | JPAKE_BN_CLEAR_FREE(pctx->g_x1); | ||
122 | JPAKE_BN_CLEAR_FREE(pctx->g_x2); | ||
123 | JPAKE_BN_CLEAR_FREE(pctx->g_x3); | ||
124 | JPAKE_BN_CLEAR_FREE(pctx->g_x4); | ||
125 | JPAKE_BN_CLEAR_FREE(pctx->a); | ||
126 | JPAKE_BN_CLEAR_FREE(pctx->b); | ||
127 | |||
128 | JPAKE_BUF_CLEAR_FREE(pctx->client_id, pctx->client_id_len); | ||
129 | JPAKE_BUF_CLEAR_FREE(pctx->server_id, pctx->server_id_len); | ||
130 | JPAKE_BUF_CLEAR_FREE(pctx->h_k_cid_sessid, pctx->h_k_cid_sessid_len); | ||
131 | JPAKE_BUF_CLEAR_FREE(pctx->h_k_sid_sessid, pctx->h_k_sid_sessid_len); | ||
132 | |||
133 | #undef JPAKE_BN_CLEAR_FREE | ||
134 | #undef JPAKE_BUF_CLEAR_FREE | ||
135 | |||
136 | bzero(pctx, sizeof(*pctx)); | ||
137 | free(pctx); | ||
138 | } | ||
139 | |||
140 | /* dump entire jpake_ctx. NB. includes private values! */ | ||
141 | void | ||
142 | jpake_dump(struct jpake_ctx *pctx, const char *fmt, ...) | ||
143 | { | ||
144 | char *out; | ||
145 | va_list args; | ||
146 | |||
147 | out = NULL; | ||
148 | va_start(args, fmt); | ||
149 | vasprintf(&out, fmt, args); | ||
150 | va_end(args); | ||
151 | if (out == NULL) | ||
152 | fatal("%s: vasprintf failed", __func__); | ||
153 | |||
154 | debug3("%s: %s (ctx at %p)", __func__, out, pctx); | ||
155 | if (pctx == NULL) { | ||
156 | free(out); | ||
157 | return; | ||
158 | } | ||
159 | |||
160 | #define JPAKE_DUMP_BN(a) do { \ | ||
161 | if ((a) != NULL) \ | ||
162 | JPAKE_DEBUG_BN(((a), "%s = ", #a)); \ | ||
163 | } while (0) | ||
164 | #define JPAKE_DUMP_BUF(a, b) do { \ | ||
165 | if ((a) != NULL) \ | ||
166 | JPAKE_DEBUG_BUF((a, b, "%s", #a)); \ | ||
167 | } while (0) | ||
168 | |||
169 | JPAKE_DUMP_BN(pctx->s); | ||
170 | JPAKE_DUMP_BN(pctx->k); | ||
171 | JPAKE_DUMP_BN(pctx->x1); | ||
172 | JPAKE_DUMP_BN(pctx->x2); | ||
173 | JPAKE_DUMP_BN(pctx->x3); | ||
174 | JPAKE_DUMP_BN(pctx->x4); | ||
175 | JPAKE_DUMP_BN(pctx->g_x1); | ||
176 | JPAKE_DUMP_BN(pctx->g_x2); | ||
177 | JPAKE_DUMP_BN(pctx->g_x3); | ||
178 | JPAKE_DUMP_BN(pctx->g_x4); | ||
179 | JPAKE_DUMP_BN(pctx->a); | ||
180 | JPAKE_DUMP_BN(pctx->b); | ||
181 | |||
182 | JPAKE_DUMP_BUF(pctx->client_id, pctx->client_id_len); | ||
183 | JPAKE_DUMP_BUF(pctx->server_id, pctx->server_id_len); | ||
184 | JPAKE_DUMP_BUF(pctx->h_k_cid_sessid, pctx->h_k_cid_sessid_len); | ||
185 | JPAKE_DUMP_BUF(pctx->h_k_sid_sessid, pctx->h_k_sid_sessid_len); | ||
186 | |||
187 | debug3("%s: %s done", __func__, out); | ||
188 | free(out); | ||
189 | } | ||
190 | |||
191 | /* Shared parts of step 1 exchange calculation */ | ||
192 | void | ||
193 | jpake_step1(struct modp_group *grp, | ||
194 | u_char **id, u_int *id_len, | ||
195 | BIGNUM **priv1, BIGNUM **priv2, BIGNUM **g_priv1, BIGNUM **g_priv2, | ||
196 | u_char **priv1_proof, u_int *priv1_proof_len, | ||
197 | u_char **priv2_proof, u_int *priv2_proof_len) | ||
198 | { | ||
199 | BN_CTX *bn_ctx; | ||
200 | |||
201 | if ((bn_ctx = BN_CTX_new()) == NULL) | ||
202 | fatal("%s: BN_CTX_new", __func__); | ||
203 | |||
204 | /* Random nonce to prevent replay */ | ||
205 | *id = xmalloc(KZP_ID_LEN); | ||
206 | *id_len = KZP_ID_LEN; | ||
207 | arc4random_buf(*id, *id_len); | ||
208 | |||
209 | /* | ||
210 | * x1/x3 is a random element of Zq | ||
211 | * x2/x4 is a random element of Z*q | ||
212 | * We also exclude [1] from x1/x3 candidates and [0, 1] from | ||
213 | * x2/x4 candiates to avoid possible degeneracy (i.e. g^0, g^1). | ||
214 | */ | ||
215 | if ((*priv1 = bn_rand_range_gt_one(grp->q)) == NULL || | ||
216 | (*priv2 = bn_rand_range_gt_one(grp->q)) == NULL) | ||
217 | fatal("%s: bn_rand_range_gt_one", __func__); | ||
218 | |||
219 | /* | ||
220 | * client: g_x1 = g^x1 mod p / server: g_x3 = g^x3 mod p | ||
221 | * client: g_x2 = g^x2 mod p / server: g_x4 = g^x4 mod p | ||
222 | */ | ||
223 | if ((*g_priv1 = BN_new()) == NULL || | ||
224 | (*g_priv2 = BN_new()) == NULL) | ||
225 | fatal("%s: BN_new", __func__); | ||
226 | if (BN_mod_exp(*g_priv1, grp->g, *priv1, grp->p, bn_ctx) == -1) | ||
227 | fatal("%s: BN_mod_exp", __func__); | ||
228 | if (BN_mod_exp(*g_priv2, grp->g, *priv2, grp->p, bn_ctx) == -1) | ||
229 | fatal("%s: BN_mod_exp", __func__); | ||
230 | |||
231 | /* Generate proofs for holding x1/x3 and x2/x4 */ | ||
232 | if (schnorr_sign_buf(grp->p, grp->q, grp->g, | ||
233 | *priv1, *g_priv1, *id, *id_len, | ||
234 | priv1_proof, priv1_proof_len) != 0) | ||
235 | fatal("%s: schnorr_sign", __func__); | ||
236 | if (schnorr_sign_buf(grp->p, grp->q, grp->g, | ||
237 | *priv2, *g_priv2, *id, *id_len, | ||
238 | priv2_proof, priv2_proof_len) != 0) | ||
239 | fatal("%s: schnorr_sign", __func__); | ||
240 | |||
241 | BN_CTX_free(bn_ctx); | ||
242 | } | ||
243 | |||
244 | /* Shared parts of step 2 exchange calculation */ | ||
245 | void | ||
246 | jpake_step2(struct modp_group *grp, BIGNUM *s, | ||
247 | BIGNUM *mypub1, BIGNUM *theirpub1, BIGNUM *theirpub2, BIGNUM *mypriv2, | ||
248 | const u_char *theirid, u_int theirid_len, | ||
249 | const u_char *myid, u_int myid_len, | ||
250 | const u_char *theirpub1_proof, u_int theirpub1_proof_len, | ||
251 | const u_char *theirpub2_proof, u_int theirpub2_proof_len, | ||
252 | BIGNUM **newpub, | ||
253 | u_char **newpub_exponent_proof, u_int *newpub_exponent_proof_len) | ||
254 | { | ||
255 | BN_CTX *bn_ctx; | ||
256 | BIGNUM *tmp, *exponent; | ||
257 | |||
258 | /* Validate peer's step 1 values */ | ||
259 | if (BN_cmp(theirpub1, BN_value_one()) <= 0) | ||
260 | fatal("%s: theirpub1 <= 1", __func__); | ||
261 | if (BN_cmp(theirpub1, grp->p) >= 0) | ||
262 | fatal("%s: theirpub1 >= p", __func__); | ||
263 | if (BN_cmp(theirpub2, BN_value_one()) <= 0) | ||
264 | fatal("%s: theirpub2 <= 1", __func__); | ||
265 | if (BN_cmp(theirpub2, grp->p) >= 0) | ||
266 | fatal("%s: theirpub2 >= p", __func__); | ||
267 | |||
268 | if (schnorr_verify_buf(grp->p, grp->q, grp->g, theirpub1, | ||
269 | theirid, theirid_len, theirpub1_proof, theirpub1_proof_len) != 1) | ||
270 | fatal("%s: schnorr_verify theirpub1 failed", __func__); | ||
271 | if (schnorr_verify_buf(grp->p, grp->q, grp->g, theirpub2, | ||
272 | theirid, theirid_len, theirpub2_proof, theirpub2_proof_len) != 1) | ||
273 | fatal("%s: schnorr_verify theirpub2 failed", __func__); | ||
274 | |||
275 | if ((bn_ctx = BN_CTX_new()) == NULL) | ||
276 | fatal("%s: BN_CTX_new", __func__); | ||
277 | |||
278 | if ((*newpub = BN_new()) == NULL || | ||
279 | (tmp = BN_new()) == NULL || | ||
280 | (exponent = BN_new()) == NULL) | ||
281 | fatal("%s: BN_new", __func__); | ||
282 | |||
283 | /* | ||
284 | * client: exponent = x2 * s mod p | ||
285 | * server: exponent = x4 * s mod p | ||
286 | */ | ||
287 | if (BN_mod_mul(exponent, mypriv2, s, grp->q, bn_ctx) != 1) | ||
288 | fatal("%s: BN_mod_mul (exponent = mypriv2 * s mod p)", | ||
289 | __func__); | ||
290 | |||
291 | /* | ||
292 | * client: tmp = g^(x1 + x3 + x4) mod p | ||
293 | * server: tmp = g^(x1 + x2 + x3) mod p | ||
294 | */ | ||
295 | if (BN_mod_mul(tmp, mypub1, theirpub1, grp->p, bn_ctx) != 1) | ||
296 | fatal("%s: BN_mod_mul (tmp = mypub1 * theirpub1 mod p)", | ||
297 | __func__); | ||
298 | if (BN_mod_mul(tmp, tmp, theirpub2, grp->p, bn_ctx) != 1) | ||
299 | fatal("%s: BN_mod_mul (tmp = tmp * theirpub2 mod p)", __func__); | ||
300 | |||
301 | /* | ||
302 | * client: a = tmp^exponent = g^((x1+x3+x4) * x2 * s) mod p | ||
303 | * server: b = tmp^exponent = g^((x1+x2+x3) * x4 * s) mod p | ||
304 | */ | ||
305 | if (BN_mod_exp(*newpub, tmp, exponent, grp->p, bn_ctx) != 1) | ||
306 | fatal("%s: BN_mod_mul (newpub = tmp^exponent mod p)", __func__); | ||
307 | |||
308 | JPAKE_DEBUG_BN((tmp, "%s: tmp = ", __func__)); | ||
309 | JPAKE_DEBUG_BN((exponent, "%s: exponent = ", __func__)); | ||
310 | |||
311 | /* Note the generator here is 'tmp', not g */ | ||
312 | if (schnorr_sign_buf(grp->p, grp->q, tmp, exponent, *newpub, | ||
313 | myid, myid_len, | ||
314 | newpub_exponent_proof, newpub_exponent_proof_len) != 0) | ||
315 | fatal("%s: schnorr_sign newpub", __func__); | ||
316 | |||
317 | BN_clear_free(tmp); /* XXX stash for later use? */ | ||
318 | BN_clear_free(exponent); /* XXX stash for later use? (yes, in conf) */ | ||
319 | |||
320 | BN_CTX_free(bn_ctx); | ||
321 | } | ||
322 | |||
323 | /* Confirmation hash calculation */ | ||
324 | void | ||
325 | jpake_confirm_hash(const BIGNUM *k, | ||
326 | const u_char *endpoint_id, u_int endpoint_id_len, | ||
327 | const u_char *sess_id, u_int sess_id_len, | ||
328 | u_char **confirm_hash, u_int *confirm_hash_len) | ||
329 | { | ||
330 | Buffer b; | ||
331 | |||
332 | /* | ||
333 | * Calculate confirmation proof: | ||
334 | * client: H(k || client_id || session_id) | ||
335 | * server: H(k || server_id || session_id) | ||
336 | */ | ||
337 | buffer_init(&b); | ||
338 | buffer_put_bignum2(&b, k); | ||
339 | buffer_put_string(&b, endpoint_id, endpoint_id_len); | ||
340 | buffer_put_string(&b, sess_id, sess_id_len); | ||
341 | if (hash_buffer(buffer_ptr(&b), buffer_len(&b), EVP_sha256(), | ||
342 | confirm_hash, confirm_hash_len) != 0) | ||
343 | fatal("%s: hash_buffer", __func__); | ||
344 | buffer_free(&b); | ||
345 | } | ||
346 | |||
347 | /* Shared parts of key derivation and confirmation calculation */ | ||
348 | void | ||
349 | jpake_key_confirm(struct modp_group *grp, BIGNUM *s, BIGNUM *step2_val, | ||
350 | BIGNUM *mypriv2, BIGNUM *mypub1, BIGNUM *mypub2, | ||
351 | BIGNUM *theirpub1, BIGNUM *theirpub2, | ||
352 | const u_char *my_id, u_int my_id_len, | ||
353 | const u_char *their_id, u_int their_id_len, | ||
354 | const u_char *sess_id, u_int sess_id_len, | ||
355 | const u_char *theirpriv2_s_proof, u_int theirpriv2_s_proof_len, | ||
356 | BIGNUM **k, | ||
357 | u_char **confirm_hash, u_int *confirm_hash_len) | ||
358 | { | ||
359 | BN_CTX *bn_ctx; | ||
360 | BIGNUM *tmp; | ||
361 | |||
362 | if ((bn_ctx = BN_CTX_new()) == NULL) | ||
363 | fatal("%s: BN_CTX_new", __func__); | ||
364 | if ((tmp = BN_new()) == NULL || | ||
365 | (*k = BN_new()) == NULL) | ||
366 | fatal("%s: BN_new", __func__); | ||
367 | |||
368 | /* Validate step 2 values */ | ||
369 | if (BN_cmp(step2_val, BN_value_one()) <= 0) | ||
370 | fatal("%s: step2_val <= 1", __func__); | ||
371 | if (BN_cmp(step2_val, grp->p) >= 0) | ||
372 | fatal("%s: step2_val >= p", __func__); | ||
373 | |||
374 | /* | ||
375 | * theirpriv2_s_proof is calculated with a different generator: | ||
376 | * tmp = g^(mypriv1+mypriv2+theirpub1) = g^mypub1*g^mypub2*g^theirpub1 | ||
377 | * Calculate it here so we can check the signature. | ||
378 | */ | ||
379 | if (BN_mod_mul(tmp, mypub1, mypub2, grp->p, bn_ctx) != 1) | ||
380 | fatal("%s: BN_mod_mul (tmp = mypub1 * mypub2 mod p)", __func__); | ||
381 | if (BN_mod_mul(tmp, tmp, theirpub1, grp->p, bn_ctx) != 1) | ||
382 | fatal("%s: BN_mod_mul (tmp = tmp * theirpub1 mod p)", __func__); | ||
383 | |||
384 | JPAKE_DEBUG_BN((tmp, "%s: tmp = ", __func__)); | ||
385 | |||
386 | if (schnorr_verify_buf(grp->p, grp->q, tmp, step2_val, | ||
387 | their_id, their_id_len, | ||
388 | theirpriv2_s_proof, theirpriv2_s_proof_len) != 1) | ||
389 | fatal("%s: schnorr_verify theirpriv2_s_proof failed", __func__); | ||
390 | |||
391 | /* | ||
392 | * Derive shared key: | ||
393 | * client: k = (b / g^(x2*x4*s))^x2 = g^((x1+x3)*x2*x4*s) | ||
394 | * server: k = (a / g^(x2*x4*s))^x4 = g^((x1+x3)*x2*x4*s) | ||
395 | * | ||
396 | * Computed as: | ||
397 | * client: k = (g_x4^(q - (x2 * s)) * b)^x2 mod p | ||
398 | * server: k = (g_x2^(q - (x4 * s)) * b)^x4 mod p | ||
399 | */ | ||
400 | if (BN_mul(tmp, mypriv2, s, bn_ctx) != 1) | ||
401 | fatal("%s: BN_mul (tmp = mypriv2 * s)", __func__); | ||
402 | if (BN_mod_sub(tmp, grp->q, tmp, grp->q, bn_ctx) != 1) | ||
403 | fatal("%s: BN_mod_sub (tmp = q - tmp mod q)", __func__); | ||
404 | if (BN_mod_exp(tmp, theirpub2, tmp, grp->p, bn_ctx) != 1) | ||
405 | fatal("%s: BN_mod_exp (tmp = theirpub2^tmp) mod p", __func__); | ||
406 | if (BN_mod_mul(tmp, tmp, step2_val, grp->p, bn_ctx) != 1) | ||
407 | fatal("%s: BN_mod_mul (tmp = tmp * step2_val) mod p", __func__); | ||
408 | if (BN_mod_exp(*k, tmp, mypriv2, grp->p, bn_ctx) != 1) | ||
409 | fatal("%s: BN_mod_exp (k = tmp^mypriv2) mod p", __func__); | ||
410 | |||
411 | BN_CTX_free(bn_ctx); | ||
412 | BN_clear_free(tmp); | ||
413 | |||
414 | jpake_confirm_hash(*k, my_id, my_id_len, sess_id, sess_id_len, | ||
415 | confirm_hash, confirm_hash_len); | ||
416 | } | ||
417 | |||
418 | /* | ||
419 | * Calculate and check confirmation hash from peer. Returns 1 on success | ||
420 | * 0 on failure/mismatch. | ||
421 | */ | ||
422 | int | ||
423 | jpake_check_confirm(const BIGNUM *k, | ||
424 | const u_char *peer_id, u_int peer_id_len, | ||
425 | const u_char *sess_id, u_int sess_id_len, | ||
426 | const u_char *peer_confirm_hash, u_int peer_confirm_hash_len) | ||
427 | { | ||
428 | u_char *expected_confirm_hash; | ||
429 | u_int expected_confirm_hash_len; | ||
430 | int success = 0; | ||
431 | |||
432 | /* Calculate and verify expected confirmation hash */ | ||
433 | jpake_confirm_hash(k, peer_id, peer_id_len, sess_id, sess_id_len, | ||
434 | &expected_confirm_hash, &expected_confirm_hash_len); | ||
435 | |||
436 | JPAKE_DEBUG_BUF((expected_confirm_hash, expected_confirm_hash_len, | ||
437 | "%s: expected confirm hash", __func__)); | ||
438 | JPAKE_DEBUG_BUF((peer_confirm_hash, peer_confirm_hash_len, | ||
439 | "%s: received confirm hash", __func__)); | ||
440 | |||
441 | if (peer_confirm_hash_len != expected_confirm_hash_len) | ||
442 | error("%s: confirmation length mismatch (my %u them %u)", | ||
443 | __func__, expected_confirm_hash_len, peer_confirm_hash_len); | ||
444 | else if (timingsafe_bcmp(peer_confirm_hash, expected_confirm_hash, | ||
445 | expected_confirm_hash_len) == 0) | ||
446 | success = 1; | ||
447 | bzero(expected_confirm_hash, expected_confirm_hash_len); | ||
448 | free(expected_confirm_hash); | ||
449 | debug3("%s: success = %d", __func__, success); | ||
450 | return success; | ||
451 | } | ||
452 | |||
453 | /* XXX main() function with tests */ | ||
454 | |||
455 | #endif /* JPAKE */ | ||
456 | |||
diff --git a/jpake.h b/jpake.h deleted file mode 100644 index a3f2cf025..000000000 --- a/jpake.h +++ /dev/null | |||
@@ -1,114 +0,0 @@ | |||
1 | /* $OpenBSD: jpake.h,v 1.2 2009/03/05 07:18:19 djm Exp $ */ | ||
2 | /* | ||
3 | * Copyright (c) 2008 Damien Miller. All rights reserved. | ||
4 | * | ||
5 | * Permission to use, copy, modify, and distribute this software for any | ||
6 | * purpose with or without fee is hereby granted, provided that the above | ||
7 | * copyright notice and this permission notice appear in all copies. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
10 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
11 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
12 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
13 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
16 | */ | ||
17 | |||
18 | #ifndef JPAKE_H | ||
19 | #define JPAKE_H | ||
20 | |||
21 | #include <sys/types.h> | ||
22 | |||
23 | #include <openssl/bn.h> | ||
24 | |||
25 | /* Set JPAKE_DEBUG in CFLAGS for privacy-violating debugging */ | ||
26 | #ifndef JPAKE_DEBUG | ||
27 | # define JPAKE_DEBUG_BN(a) | ||
28 | # define JPAKE_DEBUG_BUF(a) | ||
29 | # define JPAKE_DEBUG_CTX(a) | ||
30 | #else | ||
31 | # define JPAKE_DEBUG_BN(a) debug3_bn a | ||
32 | # define JPAKE_DEBUG_BUF(a) debug3_buf a | ||
33 | # define JPAKE_DEBUG_CTX(a) jpake_dump a | ||
34 | #endif /* JPAKE_DEBUG */ | ||
35 | |||
36 | #define KZP_ID_LEN 16 /* Length of client and server IDs */ | ||
37 | |||
38 | struct jpake_ctx { | ||
39 | /* Parameters */ | ||
40 | struct modp_group *grp; | ||
41 | |||
42 | /* Private values shared by client and server */ | ||
43 | BIGNUM *s; /* Secret (salted, crypted password) */ | ||
44 | BIGNUM *k; /* Derived key */ | ||
45 | |||
46 | /* Client private values (NULL for server) */ | ||
47 | BIGNUM *x1; /* random in Zq */ | ||
48 | BIGNUM *x2; /* random in Z*q */ | ||
49 | |||
50 | /* Server private values (NULL for server) */ | ||
51 | BIGNUM *x3; /* random in Zq */ | ||
52 | BIGNUM *x4; /* random in Z*q */ | ||
53 | |||
54 | /* Step 1: C->S */ | ||
55 | u_char *client_id; /* Anti-replay nonce */ | ||
56 | u_int client_id_len; | ||
57 | BIGNUM *g_x1; /* g^x1 */ | ||
58 | BIGNUM *g_x2; /* g^x2 */ | ||
59 | |||
60 | /* Step 1: S->C */ | ||
61 | u_char *server_id; /* Anti-replay nonce */ | ||
62 | u_int server_id_len; | ||
63 | BIGNUM *g_x3; /* g^x3 */ | ||
64 | BIGNUM *g_x4; /* g^x4 */ | ||
65 | |||
66 | /* Step 2: C->S */ | ||
67 | BIGNUM *a; /* g^((x1+x3+x4)*x2*s) */ | ||
68 | |||
69 | /* Step 2: S->C */ | ||
70 | BIGNUM *b; /* g^((x1+x2+x3)*x4*s) */ | ||
71 | |||
72 | /* Confirmation: C->S */ | ||
73 | u_char *h_k_cid_sessid; /* H(k || client_id || session_id) */ | ||
74 | u_int h_k_cid_sessid_len; | ||
75 | |||
76 | /* Confirmation: S->C */ | ||
77 | u_char *h_k_sid_sessid; /* H(k || server_id || session_id) */ | ||
78 | u_int h_k_sid_sessid_len; | ||
79 | }; | ||
80 | |||
81 | /* jpake.c */ | ||
82 | struct modp_group *jpake_default_group(void); | ||
83 | void jpake_dump(struct jpake_ctx *, const char *, ...) | ||
84 | __attribute__((__nonnull__ (2))) | ||
85 | __attribute__((format(printf, 2, 3))); | ||
86 | struct jpake_ctx *jpake_new(void); | ||
87 | void jpake_free(struct jpake_ctx *); | ||
88 | |||
89 | void jpake_step1(struct modp_group *, u_char **, u_int *, | ||
90 | BIGNUM **, BIGNUM **, BIGNUM **, BIGNUM **, | ||
91 | u_char **, u_int *, u_char **, u_int *); | ||
92 | |||
93 | void jpake_step2(struct modp_group *, BIGNUM *, | ||
94 | BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *, | ||
95 | const u_char *, u_int, const u_char *, u_int, | ||
96 | const u_char *, u_int, const u_char *, u_int, | ||
97 | BIGNUM **, u_char **, u_int *); | ||
98 | |||
99 | void jpake_confirm_hash(const BIGNUM *, | ||
100 | const u_char *, u_int, | ||
101 | const u_char *, u_int, | ||
102 | u_char **, u_int *); | ||
103 | |||
104 | void jpake_key_confirm(struct modp_group *, BIGNUM *, BIGNUM *, | ||
105 | BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *, | ||
106 | const u_char *, u_int, const u_char *, u_int, | ||
107 | const u_char *, u_int, const u_char *, u_int, | ||
108 | BIGNUM **, u_char **, u_int *); | ||
109 | |||
110 | int jpake_check_confirm(const BIGNUM *, const u_char *, u_int, | ||
111 | const u_char *, u_int, const u_char *, u_int); | ||
112 | |||
113 | #endif /* JPAKE_H */ | ||
114 | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: kex.c,v 1.97 2014/01/25 20:35:37 markus Exp $ */ | 1 | /* $OpenBSD: kex.c,v 1.98 2014/02/02 03:44:31 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -666,8 +666,8 @@ derive_ssh1_session_id(BIGNUM *host_modulus, BIGNUM *server_modulus, | |||
666 | fatal("%s: ssh_digest_final failed", __func__); | 666 | fatal("%s: ssh_digest_final failed", __func__); |
667 | memcpy(id, obuf, ssh_digest_bytes(SSH_DIGEST_MD5)); | 667 | memcpy(id, obuf, ssh_digest_bytes(SSH_DIGEST_MD5)); |
668 | 668 | ||
669 | memset(nbuf, 0, sizeof(nbuf)); | 669 | explicit_bzero(nbuf, sizeof(nbuf)); |
670 | memset(obuf, 0, sizeof(obuf)); | 670 | explicit_bzero(obuf, sizeof(obuf)); |
671 | } | 671 | } |
672 | 672 | ||
673 | #if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH) | 673 | #if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH) |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: kex.h,v 1.61 2014/01/25 10:12:50 dtucker Exp $ */ | 1 | /* $OpenBSD: kex.h,v 1.62 2014/01/27 18:58:14 markus Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. | 4 | * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. |
@@ -105,9 +105,8 @@ struct Mac { | |||
105 | u_int key_len; | 105 | u_int key_len; |
106 | int type; | 106 | int type; |
107 | int etm; /* Encrypt-then-MAC */ | 107 | int etm; /* Encrypt-then-MAC */ |
108 | const EVP_MD *evp_md; | 108 | struct ssh_hmac_ctx *hmac_ctx; |
109 | HMAC_CTX evp_ctx; | 109 | struct umac_ctx *umac_ctx; |
110 | struct umac_ctx *umac_ctx; | ||
111 | }; | 110 | }; |
112 | struct Comp { | 111 | struct Comp { |
113 | int type; | 112 | int type; |
diff --git a/kexc25519.c b/kexc25519.c index 48ca4aaa2..ee79b4327 100644 --- a/kexc25519.c +++ b/kexc25519.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: kexc25519.c,v 1.4 2014/01/12 08:13:13 djm Exp $ */ | 1 | /* $OpenBSD: kexc25519.c,v 1.5 2014/01/31 16:39:19 tedu Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2001, 2013 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2001, 2013 Markus Friedl. All rights reserved. |
4 | * Copyright (c) 2010 Damien Miller. All rights reserved. | 4 | * Copyright (c) 2010 Damien Miller. All rights reserved. |
@@ -70,7 +70,7 @@ kexc25519_shared_key(const u_char key[CURVE25519_SIZE], | |||
70 | #endif | 70 | #endif |
71 | buffer_clear(out); | 71 | buffer_clear(out); |
72 | buffer_put_bignum2_from_string(out, shared_key, CURVE25519_SIZE); | 72 | buffer_put_bignum2_from_string(out, shared_key, CURVE25519_SIZE); |
73 | memset(shared_key, 0, CURVE25519_SIZE); /* XXX explicit_bzero() */ | 73 | explicit_bzero(shared_key, CURVE25519_SIZE); |
74 | } | 74 | } |
75 | 75 | ||
76 | void | 76 | void |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: kexdhc.c,v 1.14 2014/01/12 08:13:13 djm Exp $ */ | 1 | /* $OpenBSD: kexdhc.c,v 1.15 2014/02/02 03:44:31 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2001 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2001 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -124,7 +124,7 @@ kexdh_client(Kex *kex) | |||
124 | fatal("kexdh_client: BN_new failed"); | 124 | fatal("kexdh_client: BN_new failed"); |
125 | if (BN_bin2bn(kbuf, kout, shared_secret) == NULL) | 125 | if (BN_bin2bn(kbuf, kout, shared_secret) == NULL) |
126 | fatal("kexdh_client: BN_bin2bn failed"); | 126 | fatal("kexdh_client: BN_bin2bn failed"); |
127 | memset(kbuf, 0, klen); | 127 | explicit_bzero(kbuf, klen); |
128 | free(kbuf); | 128 | free(kbuf); |
129 | 129 | ||
130 | /* calc and verify H */ | 130 | /* calc and verify H */ |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: kexdhs.c,v 1.17 2014/01/12 08:13:13 djm Exp $ */ | 1 | /* $OpenBSD: kexdhs.c,v 1.18 2014/02/02 03:44:31 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2001 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2001 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -110,7 +110,7 @@ kexdh_server(Kex *kex) | |||
110 | fatal("kexdh_server: BN_new failed"); | 110 | fatal("kexdh_server: BN_new failed"); |
111 | if (BN_bin2bn(kbuf, kout, shared_secret) == NULL) | 111 | if (BN_bin2bn(kbuf, kout, shared_secret) == NULL) |
112 | fatal("kexdh_server: BN_bin2bn failed"); | 112 | fatal("kexdh_server: BN_bin2bn failed"); |
113 | memset(kbuf, 0, klen); | 113 | explicit_bzero(kbuf, klen); |
114 | free(kbuf); | 114 | free(kbuf); |
115 | 115 | ||
116 | key_to_blob(server_host_public, &server_host_key_blob, &sbloblen); | 116 | key_to_blob(server_host_public, &server_host_key_blob, &sbloblen); |
diff --git a/kexecdhc.c b/kexecdhc.c index e3d1cf5f9..2f7629cca 100644 --- a/kexecdhc.c +++ b/kexecdhc.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: kexecdhc.c,v 1.6 2014/01/12 08:13:13 djm Exp $ */ | 1 | /* $OpenBSD: kexecdhc.c,v 1.7 2014/02/02 03:44:31 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2001 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2001 Markus Friedl. All rights reserved. |
4 | * Copyright (c) 2010 Damien Miller. All rights reserved. | 4 | * Copyright (c) 2010 Damien Miller. All rights reserved. |
@@ -119,7 +119,7 @@ kexecdh_client(Kex *kex) | |||
119 | fatal("%s: BN_new failed", __func__); | 119 | fatal("%s: BN_new failed", __func__); |
120 | if (BN_bin2bn(kbuf, klen, shared_secret) == NULL) | 120 | if (BN_bin2bn(kbuf, klen, shared_secret) == NULL) |
121 | fatal("%s: BN_bin2bn failed", __func__); | 121 | fatal("%s: BN_bin2bn failed", __func__); |
122 | memset(kbuf, 0, klen); | 122 | explicit_bzero(kbuf, klen); |
123 | free(kbuf); | 123 | free(kbuf); |
124 | 124 | ||
125 | /* calc and verify H */ | 125 | /* calc and verify H */ |
diff --git a/kexecdhs.c b/kexecdhs.c index 6fbb79c9d..2700b7219 100644 --- a/kexecdhs.c +++ b/kexecdhs.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: kexecdhs.c,v 1.9 2014/01/12 08:13:13 djm Exp $ */ | 1 | /* $OpenBSD: kexecdhs.c,v 1.10 2014/02/02 03:44:31 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2001 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2001 Markus Friedl. All rights reserved. |
4 | * Copyright (c) 2010 Damien Miller. All rights reserved. | 4 | * Copyright (c) 2010 Damien Miller. All rights reserved. |
@@ -103,7 +103,7 @@ kexecdh_server(Kex *kex) | |||
103 | fatal("%s: BN_new failed", __func__); | 103 | fatal("%s: BN_new failed", __func__); |
104 | if (BN_bin2bn(kbuf, klen, shared_secret) == NULL) | 104 | if (BN_bin2bn(kbuf, klen, shared_secret) == NULL) |
105 | fatal("%s: BN_bin2bn failed", __func__); | 105 | fatal("%s: BN_bin2bn failed", __func__); |
106 | memset(kbuf, 0, klen); | 106 | explicit_bzero(kbuf, klen); |
107 | free(kbuf); | 107 | free(kbuf); |
108 | 108 | ||
109 | /* calc H */ | 109 | /* calc H */ |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: kexgexc.c,v 1.16 2014/01/25 10:12:50 dtucker Exp $ */ | 1 | /* $OpenBSD: kexgexc.c,v 1.17 2014/02/02 03:44:31 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000 Niels Provos. All rights reserved. | 3 | * Copyright (c) 2000 Niels Provos. All rights reserved. |
4 | * Copyright (c) 2001 Markus Friedl. All rights reserved. | 4 | * Copyright (c) 2001 Markus Friedl. All rights reserved. |
@@ -162,7 +162,7 @@ kexgex_client(Kex *kex) | |||
162 | fatal("kexgex_client: BN_new failed"); | 162 | fatal("kexgex_client: BN_new failed"); |
163 | if (BN_bin2bn(kbuf, kout, shared_secret) == NULL) | 163 | if (BN_bin2bn(kbuf, kout, shared_secret) == NULL) |
164 | fatal("kexgex_client: BN_bin2bn failed"); | 164 | fatal("kexgex_client: BN_bin2bn failed"); |
165 | memset(kbuf, 0, klen); | 165 | explicit_bzero(kbuf, klen); |
166 | free(kbuf); | 166 | free(kbuf); |
167 | 167 | ||
168 | if (datafellows & SSH_OLD_DHGEX) | 168 | if (datafellows & SSH_OLD_DHGEX) |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: kexgexs.c,v 1.18 2014/01/12 08:13:13 djm Exp $ */ | 1 | /* $OpenBSD: kexgexs.c,v 1.19 2014/02/02 03:44:31 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000 Niels Provos. All rights reserved. | 3 | * Copyright (c) 2000 Niels Provos. All rights reserved. |
4 | * Copyright (c) 2001 Markus Friedl. All rights reserved. | 4 | * Copyright (c) 2001 Markus Friedl. All rights reserved. |
@@ -150,7 +150,7 @@ kexgex_server(Kex *kex) | |||
150 | fatal("kexgex_server: BN_new failed"); | 150 | fatal("kexgex_server: BN_new failed"); |
151 | if (BN_bin2bn(kbuf, kout, shared_secret) == NULL) | 151 | if (BN_bin2bn(kbuf, kout, shared_secret) == NULL) |
152 | fatal("kexgex_server: BN_bin2bn failed"); | 152 | fatal("kexgex_server: BN_bin2bn failed"); |
153 | memset(kbuf, 0, klen); | 153 | explicit_bzero(kbuf, klen); |
154 | free(kbuf); | 154 | free(kbuf); |
155 | 155 | ||
156 | key_to_blob(server_host_public, &server_host_key_blob, &sbloblen); | 156 | key_to_blob(server_host_public, &server_host_key_blob, &sbloblen); |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: key.c,v 1.115 2014/01/09 23:20:00 djm Exp $ */ | 1 | /* $OpenBSD: key.c,v 1.116 2014/02/02 03:44:31 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * read_bignum(): | 3 | * read_bignum(): |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -242,12 +242,12 @@ key_free(Key *k) | |||
242 | case KEY_ED25519: | 242 | case KEY_ED25519: |
243 | case KEY_ED25519_CERT: | 243 | case KEY_ED25519_CERT: |
244 | if (k->ed25519_pk) { | 244 | if (k->ed25519_pk) { |
245 | memset(k->ed25519_pk, 0, ED25519_PK_SZ); | 245 | explicit_bzero(k->ed25519_pk, ED25519_PK_SZ); |
246 | free(k->ed25519_pk); | 246 | free(k->ed25519_pk); |
247 | k->ed25519_pk = NULL; | 247 | k->ed25519_pk = NULL; |
248 | } | 248 | } |
249 | if (k->ed25519_sk) { | 249 | if (k->ed25519_sk) { |
250 | memset(k->ed25519_sk, 0, ED25519_SK_SZ); | 250 | explicit_bzero(k->ed25519_sk, ED25519_SK_SZ); |
251 | free(k->ed25519_sk); | 251 | free(k->ed25519_sk); |
252 | k->ed25519_sk = NULL; | 252 | k->ed25519_sk = NULL; |
253 | } | 253 | } |
@@ -415,7 +415,7 @@ key_fingerprint_raw(const Key *k, enum fp_type dgst_type, | |||
415 | if ((ssh_digest_memory(hash_alg, blob, len, | 415 | if ((ssh_digest_memory(hash_alg, blob, len, |
416 | retval, SSH_DIGEST_MAX_LENGTH)) != 0) | 416 | retval, SSH_DIGEST_MAX_LENGTH)) != 0) |
417 | fatal("%s: digest_memory failed", __func__); | 417 | fatal("%s: digest_memory failed", __func__); |
418 | memset(blob, 0, len); | 418 | explicit_bzero(blob, len); |
419 | free(blob); | 419 | free(blob); |
420 | *dgst_raw_length = ssh_digest_bytes(hash_alg); | 420 | *dgst_raw_length = ssh_digest_bytes(hash_alg); |
421 | } else { | 421 | } else { |
@@ -623,7 +623,7 @@ key_fingerprint(const Key *k, enum fp_type dgst_type, enum fp_rep dgst_rep) | |||
623 | dgst_rep); | 623 | dgst_rep); |
624 | break; | 624 | break; |
625 | } | 625 | } |
626 | memset(dgst_raw, 0, dgst_raw_len); | 626 | explicit_bzero(dgst_raw, dgst_raw_len); |
627 | free(dgst_raw); | 627 | free(dgst_raw); |
628 | return retval; | 628 | return retval; |
629 | } | 629 | } |
@@ -1744,7 +1744,7 @@ to_blob(const Key *key, u_char **blobp, u_int *lenp, int force_plain) | |||
1744 | *blobp = xmalloc(len); | 1744 | *blobp = xmalloc(len); |
1745 | memcpy(*blobp, buffer_ptr(&b), len); | 1745 | memcpy(*blobp, buffer_ptr(&b), len); |
1746 | } | 1746 | } |
1747 | memset(buffer_ptr(&b), 0, len); | 1747 | explicit_bzero(buffer_ptr(&b), len); |
1748 | buffer_free(&b); | 1748 | buffer_free(&b); |
1749 | return len; | 1749 | return len; |
1750 | } | 1750 | } |
@@ -14,7 +14,7 @@ | |||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
15 | */ | 15 | */ |
16 | 16 | ||
17 | /* $OpenBSD: krl.c,v 1.13 2013/07/20 22:20:42 djm Exp $ */ | 17 | /* $OpenBSD: krl.c,v 1.14 2014/01/31 16:39:19 tedu Exp $ */ |
18 | 18 | ||
19 | #include "includes.h" | 19 | #include "includes.h" |
20 | 20 | ||
@@ -238,7 +238,7 @@ insert_serial_range(struct revoked_serial_tree *rt, u_int64_t lo, u_int64_t hi) | |||
238 | struct revoked_serial rs, *ers, *crs, *irs; | 238 | struct revoked_serial rs, *ers, *crs, *irs; |
239 | 239 | ||
240 | KRL_DBG(("%s: insert %llu:%llu", __func__, lo, hi)); | 240 | KRL_DBG(("%s: insert %llu:%llu", __func__, lo, hi)); |
241 | bzero(&rs, sizeof(rs)); | 241 | memset(&rs, 0, sizeof(rs)); |
242 | rs.lo = lo; | 242 | rs.lo = lo; |
243 | rs.hi = hi; | 243 | rs.hi = hi; |
244 | ers = RB_NFIND(revoked_serial_tree, rt, &rs); | 244 | ers = RB_NFIND(revoked_serial_tree, rt, &rs); |
@@ -1115,7 +1115,7 @@ is_key_revoked(struct ssh_krl *krl, const Key *key) | |||
1115 | struct revoked_certs *rc; | 1115 | struct revoked_certs *rc; |
1116 | 1116 | ||
1117 | /* Check explicitly revoked hashes first */ | 1117 | /* Check explicitly revoked hashes first */ |
1118 | bzero(&rb, sizeof(rb)); | 1118 | memset(&rb, 0, sizeof(rb)); |
1119 | if ((rb.blob = key_fingerprint_raw(key, SSH_FP_SHA1, &rb.len)) == NULL) | 1119 | if ((rb.blob = key_fingerprint_raw(key, SSH_FP_SHA1, &rb.len)) == NULL) |
1120 | return -1; | 1120 | return -1; |
1121 | erb = RB_FIND(revoked_blob_tree, &krl->revoked_sha1s, &rb); | 1121 | erb = RB_FIND(revoked_blob_tree, &krl->revoked_sha1s, &rb); |
@@ -1126,7 +1126,7 @@ is_key_revoked(struct ssh_krl *krl, const Key *key) | |||
1126 | } | 1126 | } |
1127 | 1127 | ||
1128 | /* Next, explicit keys */ | 1128 | /* Next, explicit keys */ |
1129 | bzero(&rb, sizeof(rb)); | 1129 | memset(&rb, 0, sizeof(rb)); |
1130 | if (plain_key_blob(key, &rb.blob, &rb.len) != 0) | 1130 | if (plain_key_blob(key, &rb.blob, &rb.len) != 0) |
1131 | return -1; | 1131 | return -1; |
1132 | erb = RB_FIND(revoked_blob_tree, &krl->revoked_keys, &rb); | 1132 | erb = RB_FIND(revoked_blob_tree, &krl->revoked_keys, &rb); |
@@ -1147,7 +1147,7 @@ is_key_revoked(struct ssh_krl *krl, const Key *key) | |||
1147 | return 0; /* No entry for this CA */ | 1147 | return 0; /* No entry for this CA */ |
1148 | 1148 | ||
1149 | /* Check revocation by cert key ID */ | 1149 | /* Check revocation by cert key ID */ |
1150 | bzero(&rki, sizeof(rki)); | 1150 | memset(&rki, 0, sizeof(rki)); |
1151 | rki.key_id = key->cert->key_id; | 1151 | rki.key_id = key->cert->key_id; |
1152 | erki = RB_FIND(revoked_key_id_tree, &rc->revoked_key_ids, &rki); | 1152 | erki = RB_FIND(revoked_key_id_tree, &rc->revoked_key_ids, &rki); |
1153 | if (erki != NULL) { | 1153 | if (erki != NULL) { |
@@ -1162,7 +1162,7 @@ is_key_revoked(struct ssh_krl *krl, const Key *key) | |||
1162 | if (key_cert_is_legacy(key) || key->cert->serial == 0) | 1162 | if (key_cert_is_legacy(key) || key->cert->serial == 0) |
1163 | return 0; | 1163 | return 0; |
1164 | 1164 | ||
1165 | bzero(&rs, sizeof(rs)); | 1165 | memset(&rs, 0, sizeof(rs)); |
1166 | rs.lo = rs.hi = key->cert->serial; | 1166 | rs.lo = rs.hi = key->cert->serial; |
1167 | ers = RB_FIND(revoked_serial_tree, &rc->revoked_serials, &rs); | 1167 | ers = RB_FIND(revoked_serial_tree, &rc->revoked_serials, &rs); |
1168 | if (ers != NULL) { | 1168 | if (ers != NULL) { |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: mac.c,v 1.26 2014/01/04 17:50:55 tedu Exp $ */ | 1 | /* $OpenBSD: mac.c,v 1.28 2014/02/07 06:55:54 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2001 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2001 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -27,8 +27,6 @@ | |||
27 | 27 | ||
28 | #include <sys/types.h> | 28 | #include <sys/types.h> |
29 | 29 | ||
30 | #include <openssl/hmac.h> | ||
31 | |||
32 | #include <stdarg.h> | 30 | #include <stdarg.h> |
33 | #include <string.h> | 31 | #include <string.h> |
34 | #include <signal.h> | 32 | #include <signal.h> |
@@ -42,18 +40,20 @@ | |||
42 | #include "mac.h" | 40 | #include "mac.h" |
43 | #include "misc.h" | 41 | #include "misc.h" |
44 | 42 | ||
43 | #include "digest.h" | ||
44 | #include "hmac.h" | ||
45 | #include "umac.h" | 45 | #include "umac.h" |
46 | 46 | ||
47 | #include "openbsd-compat/openssl-compat.h" | 47 | #include "openbsd-compat/openssl-compat.h" |
48 | 48 | ||
49 | #define SSH_EVP 1 /* OpenSSL EVP-based MAC */ | 49 | #define SSH_DIGEST 1 /* SSH_DIGEST_XXX */ |
50 | #define SSH_UMAC 2 /* UMAC (not integrated with OpenSSL) */ | 50 | #define SSH_UMAC 2 /* UMAC (not integrated with OpenSSL) */ |
51 | #define SSH_UMAC128 3 | 51 | #define SSH_UMAC128 3 |
52 | 52 | ||
53 | struct macalg { | 53 | struct macalg { |
54 | char *name; | 54 | char *name; |
55 | int type; | 55 | int type; |
56 | const EVP_MD * (*mdfunc)(void); | 56 | int alg; |
57 | int truncatebits; /* truncate digest if != 0 */ | 57 | int truncatebits; /* truncate digest if != 0 */ |
58 | int key_len; /* just for UMAC */ | 58 | int key_len; /* just for UMAC */ |
59 | int len; /* just for UMAC */ | 59 | int len; /* just for UMAC */ |
@@ -62,33 +62,33 @@ struct macalg { | |||
62 | 62 | ||
63 | static const struct macalg macs[] = { | 63 | static const struct macalg macs[] = { |
64 | /* Encrypt-and-MAC (encrypt-and-authenticate) variants */ | 64 | /* Encrypt-and-MAC (encrypt-and-authenticate) variants */ |
65 | { "hmac-sha1", SSH_EVP, EVP_sha1, 0, 0, 0, 0 }, | 65 | { "hmac-sha1", SSH_DIGEST, SSH_DIGEST_SHA1, 0, 0, 0, 0 }, |
66 | { "hmac-sha1-96", SSH_EVP, EVP_sha1, 96, 0, 0, 0 }, | 66 | { "hmac-sha1-96", SSH_DIGEST, SSH_DIGEST_SHA1, 96, 0, 0, 0 }, |
67 | #ifdef HAVE_EVP_SHA256 | 67 | #ifdef HAVE_EVP_SHA256 |
68 | { "hmac-sha2-256", SSH_EVP, EVP_sha256, 0, 0, 0, 0 }, | 68 | { "hmac-sha2-256", SSH_DIGEST, SSH_DIGEST_SHA256, 0, 0, 0, 0 }, |
69 | { "hmac-sha2-512", SSH_EVP, EVP_sha512, 0, 0, 0, 0 }, | 69 | { "hmac-sha2-512", SSH_DIGEST, SSH_DIGEST_SHA512, 0, 0, 0, 0 }, |
70 | #endif | 70 | #endif |
71 | { "hmac-md5", SSH_EVP, EVP_md5, 0, 0, 0, 0 }, | 71 | { "hmac-md5", SSH_DIGEST, SSH_DIGEST_MD5, 0, 0, 0, 0 }, |
72 | { "hmac-md5-96", SSH_EVP, EVP_md5, 96, 0, 0, 0 }, | 72 | { "hmac-md5-96", SSH_DIGEST, SSH_DIGEST_MD5, 96, 0, 0, 0 }, |
73 | { "hmac-ripemd160", SSH_EVP, EVP_ripemd160, 0, 0, 0, 0 }, | 73 | { "hmac-ripemd160", SSH_DIGEST, SSH_DIGEST_RIPEMD160, 0, 0, 0, 0 }, |
74 | { "hmac-ripemd160@openssh.com", SSH_EVP, EVP_ripemd160, 0, 0, 0, 0 }, | 74 | { "hmac-ripemd160@openssh.com", SSH_DIGEST, SSH_DIGEST_RIPEMD160, 0, 0, 0, 0 }, |
75 | { "umac-64@openssh.com", SSH_UMAC, NULL, 0, 128, 64, 0 }, | 75 | { "umac-64@openssh.com", SSH_UMAC, 0, 0, 128, 64, 0 }, |
76 | { "umac-128@openssh.com", SSH_UMAC128, NULL, 0, 128, 128, 0 }, | 76 | { "umac-128@openssh.com", SSH_UMAC128, 0, 0, 128, 128, 0 }, |
77 | 77 | ||
78 | /* Encrypt-then-MAC variants */ | 78 | /* Encrypt-then-MAC variants */ |
79 | { "hmac-sha1-etm@openssh.com", SSH_EVP, EVP_sha1, 0, 0, 0, 1 }, | 79 | { "hmac-sha1-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_SHA1, 0, 0, 0, 1 }, |
80 | { "hmac-sha1-96-etm@openssh.com", SSH_EVP, EVP_sha1, 96, 0, 0, 1 }, | 80 | { "hmac-sha1-96-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_SHA1, 96, 0, 0, 1 }, |
81 | #ifdef HAVE_EVP_SHA256 | 81 | #ifdef HAVE_EVP_SHA256 |
82 | { "hmac-sha2-256-etm@openssh.com", SSH_EVP, EVP_sha256, 0, 0, 0, 1 }, | 82 | { "hmac-sha2-256-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_SHA256, 0, 0, 0, 1 }, |
83 | { "hmac-sha2-512-etm@openssh.com", SSH_EVP, EVP_sha512, 0, 0, 0, 1 }, | 83 | { "hmac-sha2-512-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_SHA512, 0, 0, 0, 1 }, |
84 | #endif | 84 | #endif |
85 | { "hmac-md5-etm@openssh.com", SSH_EVP, EVP_md5, 0, 0, 0, 1 }, | 85 | { "hmac-md5-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_MD5, 0, 0, 0, 1 }, |
86 | { "hmac-md5-96-etm@openssh.com", SSH_EVP, EVP_md5, 96, 0, 0, 1 }, | 86 | { "hmac-md5-96-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_MD5, 96, 0, 0, 1 }, |
87 | { "hmac-ripemd160-etm@openssh.com", SSH_EVP, EVP_ripemd160, 0, 0, 0, 1 }, | 87 | { "hmac-ripemd160-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_RIPEMD160, 0, 0, 0, 1 }, |
88 | { "umac-64-etm@openssh.com", SSH_UMAC, NULL, 0, 128, 64, 1 }, | 88 | { "umac-64-etm@openssh.com", SSH_UMAC, 0, 0, 128, 64, 1 }, |
89 | { "umac-128-etm@openssh.com", SSH_UMAC128, NULL, 0, 128, 128, 1 }, | 89 | { "umac-128-etm@openssh.com", SSH_UMAC128, 0, 0, 128, 128, 1 }, |
90 | 90 | ||
91 | { NULL, 0, NULL, 0, 0, 0, 0 } | 91 | { NULL, 0, 0, 0, 0, 0, 0 } |
92 | }; | 92 | }; |
93 | 93 | ||
94 | /* Returns a list of supported MACs separated by the specified char. */ | 94 | /* Returns a list of supported MACs separated by the specified char. */ |
@@ -113,14 +113,11 @@ mac_alg_list(char sep) | |||
113 | static void | 113 | static void |
114 | mac_setup_by_alg(Mac *mac, const struct macalg *macalg) | 114 | mac_setup_by_alg(Mac *mac, const struct macalg *macalg) |
115 | { | 115 | { |
116 | int evp_len; | ||
117 | |||
118 | mac->type = macalg->type; | 116 | mac->type = macalg->type; |
119 | if (mac->type == SSH_EVP) { | 117 | if (mac->type == SSH_DIGEST) { |
120 | mac->evp_md = macalg->mdfunc(); | 118 | if ((mac->hmac_ctx = ssh_hmac_start(macalg->alg)) == NULL) |
121 | if ((evp_len = EVP_MD_size(mac->evp_md)) <= 0) | 119 | fatal("ssh_hmac_start(alg=%d) failed", macalg->alg); |
122 | fatal("mac %s len %d", mac->name, evp_len); | 120 | mac->key_len = mac->mac_len = ssh_hmac_bytes(macalg->alg); |
123 | mac->key_len = mac->mac_len = (u_int)evp_len; | ||
124 | } else { | 121 | } else { |
125 | mac->mac_len = macalg->len / 8; | 122 | mac->mac_len = macalg->len / 8; |
126 | mac->key_len = macalg->key_len / 8; | 123 | mac->key_len = macalg->key_len / 8; |
@@ -139,9 +136,10 @@ mac_setup(Mac *mac, char *name) | |||
139 | for (m = macs; m->name != NULL; m++) { | 136 | for (m = macs; m->name != NULL; m++) { |
140 | if (strcmp(name, m->name) != 0) | 137 | if (strcmp(name, m->name) != 0) |
141 | continue; | 138 | continue; |
142 | if (mac != NULL) | 139 | if (mac != NULL) { |
143 | mac_setup_by_alg(mac, m); | 140 | mac_setup_by_alg(mac, m); |
144 | debug2("mac_setup: found %s", name); | 141 | debug2("mac_setup: setup %s", name); |
142 | } | ||
145 | return (0); | 143 | return (0); |
146 | } | 144 | } |
147 | debug2("mac_setup: unknown %s", name); | 145 | debug2("mac_setup: unknown %s", name); |
@@ -152,13 +150,12 @@ int | |||
152 | mac_init(Mac *mac) | 150 | mac_init(Mac *mac) |
153 | { | 151 | { |
154 | if (mac->key == NULL) | 152 | if (mac->key == NULL) |
155 | fatal("mac_init: no key"); | 153 | fatal("%s: no key", __func__); |
156 | switch (mac->type) { | 154 | switch (mac->type) { |
157 | case SSH_EVP: | 155 | case SSH_DIGEST: |
158 | if (mac->evp_md == NULL) | 156 | if (mac->hmac_ctx == NULL || |
157 | ssh_hmac_init(mac->hmac_ctx, mac->key, mac->key_len) < 0) | ||
159 | return -1; | 158 | return -1; |
160 | HMAC_CTX_init(&mac->evp_ctx); | ||
161 | HMAC_Init(&mac->evp_ctx, mac->key, mac->key_len, mac->evp_md); | ||
162 | return 0; | 159 | return 0; |
163 | case SSH_UMAC: | 160 | case SSH_UMAC: |
164 | mac->umac_ctx = umac_new(mac->key); | 161 | mac->umac_ctx = umac_new(mac->key); |
@@ -185,13 +182,14 @@ mac_compute(Mac *mac, u_int32_t seqno, u_char *data, int datalen) | |||
185 | mac->mac_len, sizeof(u)); | 182 | mac->mac_len, sizeof(u)); |
186 | 183 | ||
187 | switch (mac->type) { | 184 | switch (mac->type) { |
188 | case SSH_EVP: | 185 | case SSH_DIGEST: |
189 | put_u32(b, seqno); | 186 | put_u32(b, seqno); |
190 | /* reset HMAC context */ | 187 | /* reset HMAC context */ |
191 | HMAC_Init(&mac->evp_ctx, NULL, 0, NULL); | 188 | if (ssh_hmac_init(mac->hmac_ctx, NULL, 0) < 0 || |
192 | HMAC_Update(&mac->evp_ctx, b, sizeof(b)); | 189 | ssh_hmac_update(mac->hmac_ctx, b, sizeof(b)) < 0 || |
193 | HMAC_Update(&mac->evp_ctx, data, datalen); | 190 | ssh_hmac_update(mac->hmac_ctx, data, datalen) < 0 || |
194 | HMAC_Final(&mac->evp_ctx, u.m, NULL); | 191 | ssh_hmac_final(mac->hmac_ctx, u.m, sizeof(u.m)) < 0) |
192 | fatal("ssh_hmac failed"); | ||
195 | break; | 193 | break; |
196 | case SSH_UMAC: | 194 | case SSH_UMAC: |
197 | put_u64(nonce, seqno); | 195 | put_u64(nonce, seqno); |
@@ -218,9 +216,9 @@ mac_clear(Mac *mac) | |||
218 | } else if (mac->type == SSH_UMAC128) { | 216 | } else if (mac->type == SSH_UMAC128) { |
219 | if (mac->umac_ctx != NULL) | 217 | if (mac->umac_ctx != NULL) |
220 | umac128_delete(mac->umac_ctx); | 218 | umac128_delete(mac->umac_ctx); |
221 | } else if (mac->evp_md != NULL) | 219 | } else if (mac->hmac_ctx != NULL) |
222 | HMAC_cleanup(&mac->evp_ctx); | 220 | ssh_hmac_free(mac->hmac_ctx); |
223 | mac->evp_md = NULL; | 221 | mac->hmac_ctx = NULL; |
224 | mac->umac_ctx = NULL; | 222 | mac->umac_ctx = NULL; |
225 | } | 223 | } |
226 | 224 | ||
@@ -240,8 +238,6 @@ mac_valid(const char *names) | |||
240 | debug("bad mac %s [%s]", p, names); | 238 | debug("bad mac %s [%s]", p, names); |
241 | free(maclist); | 239 | free(maclist); |
242 | return (0); | 240 | return (0); |
243 | } else { | ||
244 | debug3("mac ok: %s [%s]", p, names); | ||
245 | } | 241 | } |
246 | } | 242 | } |
247 | debug3("macs ok: [%s]", names); | 243 | debug3("macs ok: [%s]", names); |
@@ -71,4 +71,4 @@ STANDARDS | |||
71 | the Secure Shell (SSH) Transport Layer Protocol, RFC 4419, March 2006, | 71 | the Secure Shell (SSH) Transport Layer Protocol, RFC 4419, March 2006, |
72 | 2006. | 72 | 2006. |
73 | 73 | ||
74 | OpenBSD 5.4 September 26, 2012 OpenBSD 5.4 | 74 | OpenBSD 5.5 September 26, 2012 OpenBSD 5.5 |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: monitor.c,v 1.128 2013/11/04 11:51:16 markus Exp $ */ | 1 | /* $OpenBSD: monitor.c,v 1.131 2014/02/02 03:44:31 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright 2002 Niels Provos <provos@citi.umich.edu> | 3 | * Copyright 2002 Niels Provos <provos@citi.umich.edu> |
4 | * Copyright 2002 Markus Friedl <markus@openbsd.org> | 4 | * Copyright 2002 Markus Friedl <markus@openbsd.org> |
@@ -95,7 +95,6 @@ | |||
95 | #include "misc.h" | 95 | #include "misc.h" |
96 | #include "compat.h" | 96 | #include "compat.h" |
97 | #include "ssh2.h" | 97 | #include "ssh2.h" |
98 | #include "jpake.h" | ||
99 | #include "roaming.h" | 98 | #include "roaming.h" |
100 | #include "authfd.h" | 99 | #include "authfd.h" |
101 | 100 | ||
@@ -161,11 +160,6 @@ int mm_answer_rsa_challenge(int, Buffer *); | |||
161 | int mm_answer_rsa_response(int, Buffer *); | 160 | int mm_answer_rsa_response(int, Buffer *); |
162 | int mm_answer_sesskey(int, Buffer *); | 161 | int mm_answer_sesskey(int, Buffer *); |
163 | int mm_answer_sessid(int, Buffer *); | 162 | int mm_answer_sessid(int, Buffer *); |
164 | int mm_answer_jpake_get_pwdata(int, Buffer *); | ||
165 | int mm_answer_jpake_step1(int, Buffer *); | ||
166 | int mm_answer_jpake_step2(int, Buffer *); | ||
167 | int mm_answer_jpake_key_confirm(int, Buffer *); | ||
168 | int mm_answer_jpake_check_confirm(int, Buffer *); | ||
169 | 163 | ||
170 | #ifdef USE_PAM | 164 | #ifdef USE_PAM |
171 | int mm_answer_pam_start(int, Buffer *); | 165 | int mm_answer_pam_start(int, Buffer *); |
@@ -254,13 +248,6 @@ struct mon_table mon_dispatch_proto20[] = { | |||
254 | {MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok}, | 248 | {MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok}, |
255 | {MONITOR_REQ_GSSCHECKMIC, MON_ISAUTH, mm_answer_gss_checkmic}, | 249 | {MONITOR_REQ_GSSCHECKMIC, MON_ISAUTH, mm_answer_gss_checkmic}, |
256 | #endif | 250 | #endif |
257 | #ifdef JPAKE | ||
258 | {MONITOR_REQ_JPAKE_GET_PWDATA, MON_ONCE, mm_answer_jpake_get_pwdata}, | ||
259 | {MONITOR_REQ_JPAKE_STEP1, MON_ISAUTH, mm_answer_jpake_step1}, | ||
260 | {MONITOR_REQ_JPAKE_STEP2, MON_ONCE, mm_answer_jpake_step2}, | ||
261 | {MONITOR_REQ_JPAKE_KEY_CONFIRM, MON_ONCE, mm_answer_jpake_key_confirm}, | ||
262 | {MONITOR_REQ_JPAKE_CHECK_CONFIRM, MON_AUTH, mm_answer_jpake_check_confirm}, | ||
263 | #endif | ||
264 | {0, 0, NULL} | 251 | {0, 0, NULL} |
265 | }; | 252 | }; |
266 | 253 | ||
@@ -427,15 +414,6 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) | |||
427 | if (!authenticated) | 414 | if (!authenticated) |
428 | authctxt->failures++; | 415 | authctxt->failures++; |
429 | } | 416 | } |
430 | #ifdef JPAKE | ||
431 | /* Cleanup JPAKE context after authentication */ | ||
432 | if (ent->flags & MON_AUTHDECIDE) { | ||
433 | if (authctxt->jpake_ctx != NULL) { | ||
434 | jpake_free(authctxt->jpake_ctx); | ||
435 | authctxt->jpake_ctx = NULL; | ||
436 | } | ||
437 | } | ||
438 | #endif | ||
439 | } | 417 | } |
440 | 418 | ||
441 | if (!authctxt->valid) | 419 | if (!authctxt->valid) |
@@ -566,7 +544,7 @@ monitor_read(struct monitor *pmonitor, struct mon_table *ent, | |||
566 | struct pollfd pfd[2]; | 544 | struct pollfd pfd[2]; |
567 | 545 | ||
568 | for (;;) { | 546 | for (;;) { |
569 | bzero(&pfd, sizeof(pfd)); | 547 | memset(&pfd, 0, sizeof(pfd)); |
570 | pfd[0].fd = pmonitor->m_sendfd; | 548 | pfd[0].fd = pmonitor->m_sendfd; |
571 | pfd[0].events = POLLIN; | 549 | pfd[0].events = POLLIN; |
572 | pfd[1].fd = pmonitor->m_log_recvfd; | 550 | pfd[1].fd = pmonitor->m_log_recvfd; |
@@ -880,7 +858,7 @@ mm_answer_authpassword(int sock, Buffer *m) | |||
880 | /* Only authenticate if the context is valid */ | 858 | /* Only authenticate if the context is valid */ |
881 | authenticated = options.password_authentication && | 859 | authenticated = options.password_authentication && |
882 | auth_password(authctxt, passwd); | 860 | auth_password(authctxt, passwd); |
883 | memset(passwd, 0, strlen(passwd)); | 861 | explicit_bzero(passwd, strlen(passwd)); |
884 | free(passwd); | 862 | free(passwd); |
885 | 863 | ||
886 | buffer_clear(m); | 864 | buffer_clear(m); |
@@ -1822,13 +1800,13 @@ monitor_apply_keystate(struct monitor *pmonitor) | |||
1822 | /* XXX inefficient for large buffers, need: buffer_init_from_string */ | 1800 | /* XXX inefficient for large buffers, need: buffer_init_from_string */ |
1823 | buffer_clear(packet_get_input()); | 1801 | buffer_clear(packet_get_input()); |
1824 | buffer_append(packet_get_input(), child_state.input, child_state.ilen); | 1802 | buffer_append(packet_get_input(), child_state.input, child_state.ilen); |
1825 | memset(child_state.input, 0, child_state.ilen); | 1803 | explicit_bzero(child_state.input, child_state.ilen); |
1826 | free(child_state.input); | 1804 | free(child_state.input); |
1827 | 1805 | ||
1828 | buffer_clear(packet_get_output()); | 1806 | buffer_clear(packet_get_output()); |
1829 | buffer_append(packet_get_output(), child_state.output, | 1807 | buffer_append(packet_get_output(), child_state.output, |
1830 | child_state.olen); | 1808 | child_state.olen); |
1831 | memset(child_state.output, 0, child_state.olen); | 1809 | explicit_bzero(child_state.output, child_state.olen); |
1832 | free(child_state.output); | 1810 | free(child_state.output); |
1833 | 1811 | ||
1834 | /* Roaming */ | 1812 | /* Roaming */ |
@@ -2159,205 +2137,3 @@ mm_answer_gss_userok(int sock, Buffer *m) | |||
2159 | } | 2137 | } |
2160 | #endif /* GSSAPI */ | 2138 | #endif /* GSSAPI */ |
2161 | 2139 | ||
2162 | #ifdef JPAKE | ||
2163 | int | ||
2164 | mm_answer_jpake_step1(int sock, Buffer *m) | ||
2165 | { | ||
2166 | struct jpake_ctx *pctx; | ||
2167 | u_char *x3_proof, *x4_proof; | ||
2168 | u_int x3_proof_len, x4_proof_len; | ||
2169 | |||
2170 | if (!options.zero_knowledge_password_authentication) | ||
2171 | fatal("zero_knowledge_password_authentication disabled"); | ||
2172 | |||
2173 | if (authctxt->jpake_ctx != NULL) | ||
2174 | fatal("%s: authctxt->jpake_ctx already set (%p)", | ||
2175 | __func__, authctxt->jpake_ctx); | ||
2176 | authctxt->jpake_ctx = pctx = jpake_new(); | ||
2177 | |||
2178 | jpake_step1(pctx->grp, | ||
2179 | &pctx->server_id, &pctx->server_id_len, | ||
2180 | &pctx->x3, &pctx->x4, &pctx->g_x3, &pctx->g_x4, | ||
2181 | &x3_proof, &x3_proof_len, | ||
2182 | &x4_proof, &x4_proof_len); | ||
2183 | |||
2184 | JPAKE_DEBUG_CTX((pctx, "step1 done in %s", __func__)); | ||
2185 | |||
2186 | buffer_clear(m); | ||
2187 | |||
2188 | buffer_put_string(m, pctx->server_id, pctx->server_id_len); | ||
2189 | buffer_put_bignum2(m, pctx->g_x3); | ||
2190 | buffer_put_bignum2(m, pctx->g_x4); | ||
2191 | buffer_put_string(m, x3_proof, x3_proof_len); | ||
2192 | buffer_put_string(m, x4_proof, x4_proof_len); | ||
2193 | |||
2194 | debug3("%s: sending step1", __func__); | ||
2195 | mm_request_send(sock, MONITOR_ANS_JPAKE_STEP1, m); | ||
2196 | |||
2197 | bzero(x3_proof, x3_proof_len); | ||
2198 | bzero(x4_proof, x4_proof_len); | ||
2199 | free(x3_proof); | ||
2200 | free(x4_proof); | ||
2201 | |||
2202 | monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_GET_PWDATA, 1); | ||
2203 | monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_STEP1, 0); | ||
2204 | |||
2205 | return 0; | ||
2206 | } | ||
2207 | |||
2208 | int | ||
2209 | mm_answer_jpake_get_pwdata(int sock, Buffer *m) | ||
2210 | { | ||
2211 | struct jpake_ctx *pctx = authctxt->jpake_ctx; | ||
2212 | char *hash_scheme, *salt; | ||
2213 | |||
2214 | if (pctx == NULL) | ||
2215 | fatal("%s: pctx == NULL", __func__); | ||
2216 | |||
2217 | auth2_jpake_get_pwdata(authctxt, &pctx->s, &hash_scheme, &salt); | ||
2218 | |||
2219 | buffer_clear(m); | ||
2220 | /* pctx->s is sensitive, not returned to slave */ | ||
2221 | buffer_put_cstring(m, hash_scheme); | ||
2222 | buffer_put_cstring(m, salt); | ||
2223 | |||
2224 | debug3("%s: sending pwdata", __func__); | ||
2225 | mm_request_send(sock, MONITOR_ANS_JPAKE_GET_PWDATA, m); | ||
2226 | |||
2227 | bzero(hash_scheme, strlen(hash_scheme)); | ||
2228 | bzero(salt, strlen(salt)); | ||
2229 | free(hash_scheme); | ||
2230 | free(salt); | ||
2231 | |||
2232 | monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_STEP2, 1); | ||
2233 | |||
2234 | return 0; | ||
2235 | } | ||
2236 | |||
2237 | int | ||
2238 | mm_answer_jpake_step2(int sock, Buffer *m) | ||
2239 | { | ||
2240 | struct jpake_ctx *pctx = authctxt->jpake_ctx; | ||
2241 | u_char *x1_proof, *x2_proof, *x4_s_proof; | ||
2242 | u_int x1_proof_len, x2_proof_len, x4_s_proof_len; | ||
2243 | |||
2244 | if (pctx == NULL) | ||
2245 | fatal("%s: pctx == NULL", __func__); | ||
2246 | |||
2247 | if ((pctx->g_x1 = BN_new()) == NULL || | ||
2248 | (pctx->g_x2 = BN_new()) == NULL) | ||
2249 | fatal("%s: BN_new", __func__); | ||
2250 | buffer_get_bignum2(m, pctx->g_x1); | ||
2251 | buffer_get_bignum2(m, pctx->g_x2); | ||
2252 | pctx->client_id = buffer_get_string(m, &pctx->client_id_len); | ||
2253 | x1_proof = buffer_get_string(m, &x1_proof_len); | ||
2254 | x2_proof = buffer_get_string(m, &x2_proof_len); | ||
2255 | |||
2256 | jpake_step2(pctx->grp, pctx->s, pctx->g_x3, | ||
2257 | pctx->g_x1, pctx->g_x2, pctx->x4, | ||
2258 | pctx->client_id, pctx->client_id_len, | ||
2259 | pctx->server_id, pctx->server_id_len, | ||
2260 | x1_proof, x1_proof_len, | ||
2261 | x2_proof, x2_proof_len, | ||
2262 | &pctx->b, | ||
2263 | &x4_s_proof, &x4_s_proof_len); | ||
2264 | |||
2265 | JPAKE_DEBUG_CTX((pctx, "step2 done in %s", __func__)); | ||
2266 | |||
2267 | bzero(x1_proof, x1_proof_len); | ||
2268 | bzero(x2_proof, x2_proof_len); | ||
2269 | free(x1_proof); | ||
2270 | free(x2_proof); | ||
2271 | |||
2272 | buffer_clear(m); | ||
2273 | |||
2274 | buffer_put_bignum2(m, pctx->b); | ||
2275 | buffer_put_string(m, x4_s_proof, x4_s_proof_len); | ||
2276 | |||
2277 | debug3("%s: sending step2", __func__); | ||
2278 | mm_request_send(sock, MONITOR_ANS_JPAKE_STEP2, m); | ||
2279 | |||
2280 | bzero(x4_s_proof, x4_s_proof_len); | ||
2281 | free(x4_s_proof); | ||
2282 | |||
2283 | monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_KEY_CONFIRM, 1); | ||
2284 | |||
2285 | return 0; | ||
2286 | } | ||
2287 | |||
2288 | int | ||
2289 | mm_answer_jpake_key_confirm(int sock, Buffer *m) | ||
2290 | { | ||
2291 | struct jpake_ctx *pctx = authctxt->jpake_ctx; | ||
2292 | u_char *x2_s_proof; | ||
2293 | u_int x2_s_proof_len; | ||
2294 | |||
2295 | if (pctx == NULL) | ||
2296 | fatal("%s: pctx == NULL", __func__); | ||
2297 | |||
2298 | if ((pctx->a = BN_new()) == NULL) | ||
2299 | fatal("%s: BN_new", __func__); | ||
2300 | buffer_get_bignum2(m, pctx->a); | ||
2301 | x2_s_proof = buffer_get_string(m, &x2_s_proof_len); | ||
2302 | |||
2303 | jpake_key_confirm(pctx->grp, pctx->s, pctx->a, | ||
2304 | pctx->x4, pctx->g_x3, pctx->g_x4, pctx->g_x1, pctx->g_x2, | ||
2305 | pctx->server_id, pctx->server_id_len, | ||
2306 | pctx->client_id, pctx->client_id_len, | ||
2307 | session_id2, session_id2_len, | ||
2308 | x2_s_proof, x2_s_proof_len, | ||
2309 | &pctx->k, | ||
2310 | &pctx->h_k_sid_sessid, &pctx->h_k_sid_sessid_len); | ||
2311 | |||
2312 | JPAKE_DEBUG_CTX((pctx, "key_confirm done in %s", __func__)); | ||
2313 | |||
2314 | bzero(x2_s_proof, x2_s_proof_len); | ||
2315 | buffer_clear(m); | ||
2316 | |||
2317 | /* pctx->k is sensitive, not sent */ | ||
2318 | buffer_put_string(m, pctx->h_k_sid_sessid, pctx->h_k_sid_sessid_len); | ||
2319 | |||
2320 | debug3("%s: sending confirmation hash", __func__); | ||
2321 | mm_request_send(sock, MONITOR_ANS_JPAKE_KEY_CONFIRM, m); | ||
2322 | |||
2323 | monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_CHECK_CONFIRM, 1); | ||
2324 | |||
2325 | return 0; | ||
2326 | } | ||
2327 | |||
2328 | int | ||
2329 | mm_answer_jpake_check_confirm(int sock, Buffer *m) | ||
2330 | { | ||
2331 | int authenticated = 0; | ||
2332 | u_char *peer_confirm_hash; | ||
2333 | u_int peer_confirm_hash_len; | ||
2334 | struct jpake_ctx *pctx = authctxt->jpake_ctx; | ||
2335 | |||
2336 | if (pctx == NULL) | ||
2337 | fatal("%s: pctx == NULL", __func__); | ||
2338 | |||
2339 | peer_confirm_hash = buffer_get_string(m, &peer_confirm_hash_len); | ||
2340 | |||
2341 | authenticated = jpake_check_confirm(pctx->k, | ||
2342 | pctx->client_id, pctx->client_id_len, | ||
2343 | session_id2, session_id2_len, | ||
2344 | peer_confirm_hash, peer_confirm_hash_len) && authctxt->valid; | ||
2345 | |||
2346 | JPAKE_DEBUG_CTX((pctx, "check_confirm done in %s", __func__)); | ||
2347 | |||
2348 | bzero(peer_confirm_hash, peer_confirm_hash_len); | ||
2349 | free(peer_confirm_hash); | ||
2350 | |||
2351 | buffer_clear(m); | ||
2352 | buffer_put_int(m, authenticated); | ||
2353 | |||
2354 | debug3("%s: sending result %d", __func__, authenticated); | ||
2355 | mm_request_send(sock, MONITOR_ANS_JPAKE_CHECK_CONFIRM, m); | ||
2356 | |||
2357 | monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_STEP1, 1); | ||
2358 | |||
2359 | auth_method = "jpake-01@openssh.com"; | ||
2360 | return authenticated; | ||
2361 | } | ||
2362 | |||
2363 | #endif /* JPAKE */ | ||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: monitor.h,v 1.17 2012/12/02 20:34:10 djm Exp $ */ | 1 | /* $OpenBSD: monitor.h,v 1.18 2014/01/29 06:18:35 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Copyright 2002 Niels Provos <provos@citi.umich.edu> | 4 | * Copyright 2002 Niels Provos <provos@citi.umich.edu> |
@@ -56,11 +56,6 @@ enum monitor_reqtype { | |||
56 | MONITOR_REQ_GSSUSEROK = 46, MONITOR_ANS_GSSUSEROK = 47, | 56 | MONITOR_REQ_GSSUSEROK = 46, MONITOR_ANS_GSSUSEROK = 47, |
57 | MONITOR_REQ_GSSCHECKMIC = 48, MONITOR_ANS_GSSCHECKMIC = 49, | 57 | MONITOR_REQ_GSSCHECKMIC = 48, MONITOR_ANS_GSSCHECKMIC = 49, |
58 | MONITOR_REQ_TERM = 50, | 58 | MONITOR_REQ_TERM = 50, |
59 | MONITOR_REQ_JPAKE_STEP1 = 52, MONITOR_ANS_JPAKE_STEP1 = 53, | ||
60 | MONITOR_REQ_JPAKE_GET_PWDATA = 54, MONITOR_ANS_JPAKE_GET_PWDATA = 55, | ||
61 | MONITOR_REQ_JPAKE_STEP2 = 56, MONITOR_ANS_JPAKE_STEP2 = 57, | ||
62 | MONITOR_REQ_JPAKE_KEY_CONFIRM = 58, MONITOR_ANS_JPAKE_KEY_CONFIRM = 59, | ||
63 | MONITOR_REQ_JPAKE_CHECK_CONFIRM = 60, MONITOR_ANS_JPAKE_CHECK_CONFIRM = 61, | ||
64 | 59 | ||
65 | MONITOR_REQ_PAM_START = 100, | 60 | MONITOR_REQ_PAM_START = 100, |
66 | MONITOR_REQ_PAM_ACCOUNT = 102, MONITOR_ANS_PAM_ACCOUNT = 103, | 61 | MONITOR_REQ_PAM_ACCOUNT = 102, MONITOR_ANS_PAM_ACCOUNT = 103, |
diff --git a/monitor_wrap.c b/monitor_wrap.c index 4ce469605..1a47e4174 100644 --- a/monitor_wrap.c +++ b/monitor_wrap.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: monitor_wrap.c,v 1.77 2013/11/06 16:52:11 markus Exp $ */ | 1 | /* $OpenBSD: monitor_wrap.c,v 1.79 2014/02/02 03:44:31 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright 2002 Niels Provos <provos@citi.umich.edu> | 3 | * Copyright 2002 Niels Provos <provos@citi.umich.edu> |
4 | * Copyright 2002 Markus Friedl <markus@openbsd.org> | 4 | * Copyright 2002 Markus Friedl <markus@openbsd.org> |
@@ -71,8 +71,6 @@ | |||
71 | #include "atomicio.h" | 71 | #include "atomicio.h" |
72 | #include "monitor_fdpass.h" | 72 | #include "monitor_fdpass.h" |
73 | #include "misc.h" | 73 | #include "misc.h" |
74 | #include "schnorr.h" | ||
75 | #include "jpake.h" | ||
76 | #include "uuencode.h" | 74 | #include "uuencode.h" |
77 | 75 | ||
78 | #include "channels.h" | 76 | #include "channels.h" |
@@ -574,7 +572,7 @@ mm_newkeys_to_blob(int mode, u_char **blobp, u_int *lenp) | |||
574 | *blobp = xmalloc(len); | 572 | *blobp = xmalloc(len); |
575 | memcpy(*blobp, buffer_ptr(&b), len); | 573 | memcpy(*blobp, buffer_ptr(&b), len); |
576 | } | 574 | } |
577 | memset(buffer_ptr(&b), 0, len); | 575 | explicit_bzero(buffer_ptr(&b), len); |
578 | buffer_free(&b); | 576 | buffer_free(&b); |
579 | return len; | 577 | return len; |
580 | } | 578 | } |
@@ -618,7 +616,7 @@ mm_send_keystate(struct monitor *monitor) | |||
618 | key = xmalloc(keylen+1); /* add 1 if keylen == 0 */ | 616 | key = xmalloc(keylen+1); /* add 1 if keylen == 0 */ |
619 | keylen = packet_get_encryption_key(key); | 617 | keylen = packet_get_encryption_key(key); |
620 | buffer_put_string(&m, key, keylen); | 618 | buffer_put_string(&m, key, keylen); |
621 | memset(key, 0, keylen); | 619 | explicit_bzero(key, keylen); |
622 | free(key); | 620 | free(key); |
623 | 621 | ||
624 | ivlen = packet_get_keyiv_len(MODE_OUT); | 622 | ivlen = packet_get_keyiv_len(MODE_OUT); |
@@ -1292,164 +1290,3 @@ mm_ssh_gssapi_userok(char *user) | |||
1292 | } | 1290 | } |
1293 | #endif /* GSSAPI */ | 1291 | #endif /* GSSAPI */ |
1294 | 1292 | ||
1295 | #ifdef JPAKE | ||
1296 | void | ||
1297 | mm_auth2_jpake_get_pwdata(Authctxt *authctxt, BIGNUM **s, | ||
1298 | char **hash_scheme, char **salt) | ||
1299 | { | ||
1300 | Buffer m; | ||
1301 | |||
1302 | debug3("%s entering", __func__); | ||
1303 | |||
1304 | buffer_init(&m); | ||
1305 | mm_request_send(pmonitor->m_recvfd, | ||
1306 | MONITOR_REQ_JPAKE_GET_PWDATA, &m); | ||
1307 | |||
1308 | debug3("%s: waiting for MONITOR_ANS_JPAKE_GET_PWDATA", __func__); | ||
1309 | mm_request_receive_expect(pmonitor->m_recvfd, | ||
1310 | MONITOR_ANS_JPAKE_GET_PWDATA, &m); | ||
1311 | |||
1312 | *hash_scheme = buffer_get_string(&m, NULL); | ||
1313 | *salt = buffer_get_string(&m, NULL); | ||
1314 | |||
1315 | buffer_free(&m); | ||
1316 | } | ||
1317 | |||
1318 | void | ||
1319 | mm_jpake_step1(struct modp_group *grp, | ||
1320 | u_char **id, u_int *id_len, | ||
1321 | BIGNUM **priv1, BIGNUM **priv2, BIGNUM **g_priv1, BIGNUM **g_priv2, | ||
1322 | u_char **priv1_proof, u_int *priv1_proof_len, | ||
1323 | u_char **priv2_proof, u_int *priv2_proof_len) | ||
1324 | { | ||
1325 | Buffer m; | ||
1326 | |||
1327 | debug3("%s entering", __func__); | ||
1328 | |||
1329 | buffer_init(&m); | ||
1330 | mm_request_send(pmonitor->m_recvfd, | ||
1331 | MONITOR_REQ_JPAKE_STEP1, &m); | ||
1332 | |||
1333 | debug3("%s: waiting for MONITOR_ANS_JPAKE_STEP1", __func__); | ||
1334 | mm_request_receive_expect(pmonitor->m_recvfd, | ||
1335 | MONITOR_ANS_JPAKE_STEP1, &m); | ||
1336 | |||
1337 | if ((*priv1 = BN_new()) == NULL || | ||
1338 | (*priv2 = BN_new()) == NULL || | ||
1339 | (*g_priv1 = BN_new()) == NULL || | ||
1340 | (*g_priv2 = BN_new()) == NULL) | ||
1341 | fatal("%s: BN_new", __func__); | ||
1342 | |||
1343 | *id = buffer_get_string(&m, id_len); | ||
1344 | /* priv1 and priv2 are, well, private */ | ||
1345 | buffer_get_bignum2(&m, *g_priv1); | ||
1346 | buffer_get_bignum2(&m, *g_priv2); | ||
1347 | *priv1_proof = buffer_get_string(&m, priv1_proof_len); | ||
1348 | *priv2_proof = buffer_get_string(&m, priv2_proof_len); | ||
1349 | |||
1350 | buffer_free(&m); | ||
1351 | } | ||
1352 | |||
1353 | void | ||
1354 | mm_jpake_step2(struct modp_group *grp, BIGNUM *s, | ||
1355 | BIGNUM *mypub1, BIGNUM *theirpub1, BIGNUM *theirpub2, BIGNUM *mypriv2, | ||
1356 | const u_char *theirid, u_int theirid_len, | ||
1357 | const u_char *myid, u_int myid_len, | ||
1358 | const u_char *theirpub1_proof, u_int theirpub1_proof_len, | ||
1359 | const u_char *theirpub2_proof, u_int theirpub2_proof_len, | ||
1360 | BIGNUM **newpub, | ||
1361 | u_char **newpub_exponent_proof, u_int *newpub_exponent_proof_len) | ||
1362 | { | ||
1363 | Buffer m; | ||
1364 | |||
1365 | debug3("%s entering", __func__); | ||
1366 | |||
1367 | buffer_init(&m); | ||
1368 | /* monitor already has all bignums except theirpub1, theirpub2 */ | ||
1369 | buffer_put_bignum2(&m, theirpub1); | ||
1370 | buffer_put_bignum2(&m, theirpub2); | ||
1371 | /* monitor already knows our id */ | ||
1372 | buffer_put_string(&m, theirid, theirid_len); | ||
1373 | buffer_put_string(&m, theirpub1_proof, theirpub1_proof_len); | ||
1374 | buffer_put_string(&m, theirpub2_proof, theirpub2_proof_len); | ||
1375 | |||
1376 | mm_request_send(pmonitor->m_recvfd, | ||
1377 | MONITOR_REQ_JPAKE_STEP2, &m); | ||
1378 | |||
1379 | debug3("%s: waiting for MONITOR_ANS_JPAKE_STEP2", __func__); | ||
1380 | mm_request_receive_expect(pmonitor->m_recvfd, | ||
1381 | MONITOR_ANS_JPAKE_STEP2, &m); | ||
1382 | |||
1383 | if ((*newpub = BN_new()) == NULL) | ||
1384 | fatal("%s: BN_new", __func__); | ||
1385 | |||
1386 | buffer_get_bignum2(&m, *newpub); | ||
1387 | *newpub_exponent_proof = buffer_get_string(&m, | ||
1388 | newpub_exponent_proof_len); | ||
1389 | |||
1390 | buffer_free(&m); | ||
1391 | } | ||
1392 | |||
1393 | void | ||
1394 | mm_jpake_key_confirm(struct modp_group *grp, BIGNUM *s, BIGNUM *step2_val, | ||
1395 | BIGNUM *mypriv2, BIGNUM *mypub1, BIGNUM *mypub2, | ||
1396 | BIGNUM *theirpub1, BIGNUM *theirpub2, | ||
1397 | const u_char *my_id, u_int my_id_len, | ||
1398 | const u_char *their_id, u_int their_id_len, | ||
1399 | const u_char *sess_id, u_int sess_id_len, | ||
1400 | const u_char *theirpriv2_s_proof, u_int theirpriv2_s_proof_len, | ||
1401 | BIGNUM **k, | ||
1402 | u_char **confirm_hash, u_int *confirm_hash_len) | ||
1403 | { | ||
1404 | Buffer m; | ||
1405 | |||
1406 | debug3("%s entering", __func__); | ||
1407 | |||
1408 | buffer_init(&m); | ||
1409 | /* monitor already has all bignums except step2_val */ | ||
1410 | buffer_put_bignum2(&m, step2_val); | ||
1411 | /* monitor already knows all the ids */ | ||
1412 | buffer_put_string(&m, theirpriv2_s_proof, theirpriv2_s_proof_len); | ||
1413 | |||
1414 | mm_request_send(pmonitor->m_recvfd, | ||
1415 | MONITOR_REQ_JPAKE_KEY_CONFIRM, &m); | ||
1416 | |||
1417 | debug3("%s: waiting for MONITOR_ANS_JPAKE_KEY_CONFIRM", __func__); | ||
1418 | mm_request_receive_expect(pmonitor->m_recvfd, | ||
1419 | MONITOR_ANS_JPAKE_KEY_CONFIRM, &m); | ||
1420 | |||
1421 | /* 'k' is sensitive and stays in the monitor */ | ||
1422 | *confirm_hash = buffer_get_string(&m, confirm_hash_len); | ||
1423 | |||
1424 | buffer_free(&m); | ||
1425 | } | ||
1426 | |||
1427 | int | ||
1428 | mm_jpake_check_confirm(const BIGNUM *k, | ||
1429 | const u_char *peer_id, u_int peer_id_len, | ||
1430 | const u_char *sess_id, u_int sess_id_len, | ||
1431 | const u_char *peer_confirm_hash, u_int peer_confirm_hash_len) | ||
1432 | { | ||
1433 | Buffer m; | ||
1434 | int success = 0; | ||
1435 | |||
1436 | debug3("%s entering", __func__); | ||
1437 | |||
1438 | buffer_init(&m); | ||
1439 | /* k is dummy in slave, ignored */ | ||
1440 | /* monitor knows all the ids */ | ||
1441 | buffer_put_string(&m, peer_confirm_hash, peer_confirm_hash_len); | ||
1442 | mm_request_send(pmonitor->m_recvfd, | ||
1443 | MONITOR_REQ_JPAKE_CHECK_CONFIRM, &m); | ||
1444 | |||
1445 | debug3("%s: waiting for MONITOR_ANS_JPAKE_CHECK_CONFIRM", __func__); | ||
1446 | mm_request_receive_expect(pmonitor->m_recvfd, | ||
1447 | MONITOR_ANS_JPAKE_CHECK_CONFIRM, &m); | ||
1448 | |||
1449 | success = buffer_get_int(&m); | ||
1450 | buffer_free(&m); | ||
1451 | |||
1452 | debug3("%s: success = %d", __func__, success); | ||
1453 | return success; | ||
1454 | } | ||
1455 | #endif /* JPAKE */ | ||
diff --git a/monitor_wrap.h b/monitor_wrap.h index 0c7f2e384..18c25010d 100644 --- a/monitor_wrap.h +++ b/monitor_wrap.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: monitor_wrap.h,v 1.23 2011/06/17 21:44:31 djm Exp $ */ | 1 | /* $OpenBSD: monitor_wrap.h,v 1.24 2014/01/29 06:18:35 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Copyright 2002 Niels Provos <provos@citi.umich.edu> | 4 | * Copyright 2002 Niels Provos <provos@citi.umich.edu> |
@@ -102,26 +102,6 @@ int mm_bsdauth_respond(void *, u_int, char **); | |||
102 | int mm_skey_query(void *, char **, char **, u_int *, char ***, u_int **); | 102 | int mm_skey_query(void *, char **, char **, u_int *, char ***, u_int **); |
103 | int mm_skey_respond(void *, u_int, char **); | 103 | int mm_skey_respond(void *, u_int, char **); |
104 | 104 | ||
105 | /* jpake */ | ||
106 | struct modp_group; | ||
107 | void mm_auth2_jpake_get_pwdata(struct Authctxt *, BIGNUM **, char **, char **); | ||
108 | void mm_jpake_step1(struct modp_group *, u_char **, u_int *, | ||
109 | BIGNUM **, BIGNUM **, BIGNUM **, BIGNUM **, | ||
110 | u_char **, u_int *, u_char **, u_int *); | ||
111 | void mm_jpake_step2(struct modp_group *, BIGNUM *, | ||
112 | BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *, | ||
113 | const u_char *, u_int, const u_char *, u_int, | ||
114 | const u_char *, u_int, const u_char *, u_int, | ||
115 | BIGNUM **, u_char **, u_int *); | ||
116 | void mm_jpake_key_confirm(struct modp_group *, BIGNUM *, BIGNUM *, | ||
117 | BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *, | ||
118 | const u_char *, u_int, const u_char *, u_int, | ||
119 | const u_char *, u_int, const u_char *, u_int, | ||
120 | BIGNUM **, u_char **, u_int *); | ||
121 | int mm_jpake_check_confirm(const BIGNUM *, | ||
122 | const u_char *, u_int, const u_char *, u_int, const u_char *, u_int); | ||
123 | |||
124 | |||
125 | /* zlib allocation hooks */ | 105 | /* zlib allocation hooks */ |
126 | 106 | ||
127 | void *mm_zalloc(struct mm_master *, u_int, u_int); | 107 | void *mm_zalloc(struct mm_master *, u_int, u_int); |
diff --git a/openbsd-compat/Makefile.in b/openbsd-compat/Makefile.in index 276646fa6..6ecfb93d5 100644 --- a/openbsd-compat/Makefile.in +++ b/openbsd-compat/Makefile.in | |||
@@ -1,4 +1,4 @@ | |||
1 | # $Id: Makefile.in,v 1.54 2013/12/07 01:37:54 djm Exp $ | 1 | # $Id: Makefile.in,v 1.55 2014/02/04 00:37:50 djm Exp $ |
2 | 2 | ||
3 | sysconfdir=@sysconfdir@ | 3 | sysconfdir=@sysconfdir@ |
4 | piddir=@piddir@ | 4 | piddir=@piddir@ |
@@ -16,7 +16,7 @@ RANLIB=@RANLIB@ | |||
16 | INSTALL=@INSTALL@ | 16 | INSTALL=@INSTALL@ |
17 | LDFLAGS=-L. @LDFLAGS@ | 17 | LDFLAGS=-L. @LDFLAGS@ |
18 | 18 | ||
19 | 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 | 19 | 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 |
20 | 20 | ||
21 | 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 | 21 | 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 |
22 | 22 | ||
diff --git a/openbsd-compat/bsd-poll.c b/openbsd-compat/bsd-poll.c index c7ef82776..73a852480 100644 --- a/openbsd-compat/bsd-poll.c +++ b/openbsd-compat/bsd-poll.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $Id: bsd-poll.c,v 1.5 2013/11/08 10:12:58 dtucker Exp $ */ | 1 | /* $Id: bsd-poll.c,v 1.6 2014/02/05 23:44:13 dtucker Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Copyright (c) 2004, 2005, 2007 Darren Tucker (dtucker at zip com au). | 4 | * 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) | |||
109 | } | 109 | } |
110 | 110 | ||
111 | out: | 111 | out: |
112 | if (readfds != NULL) | 112 | free(readfds); |
113 | free(readfds); | 113 | free(writefds); |
114 | if (writefds != NULL) | 114 | free(exceptfds); |
115 | free(writefds); | ||
116 | if (exceptfds != NULL) | ||
117 | free(exceptfds); | ||
118 | if (ret == -1) | 115 | if (ret == -1) |
119 | errno = saved_errno; | 116 | errno = saved_errno; |
120 | return ret; | 117 | return ret; |
diff --git a/openbsd-compat/explicit_bzero.c b/openbsd-compat/explicit_bzero.c new file mode 100644 index 000000000..b106741e5 --- /dev/null +++ b/openbsd-compat/explicit_bzero.c | |||
@@ -0,0 +1,20 @@ | |||
1 | /* OPENBSD ORIGINAL: lib/libc/string/explicit_bzero.c */ | ||
2 | /* $OpenBSD: explicit_bzero.c,v 1.1 2014/01/22 21:06:45 tedu Exp $ */ | ||
3 | /* | ||
4 | * Public domain. | ||
5 | * Written by Ted Unangst | ||
6 | */ | ||
7 | |||
8 | #include "includes.h" | ||
9 | |||
10 | #ifndef HAVE_EXPLICIT_BZERO | ||
11 | |||
12 | /* | ||
13 | * explicit_bzero - don't let the compiler optimize away bzero | ||
14 | */ | ||
15 | void | ||
16 | explicit_bzero(void *p, size_t n) | ||
17 | { | ||
18 | bzero(p, n); | ||
19 | } | ||
20 | #endif | ||
diff --git a/openbsd-compat/openbsd-compat.h b/openbsd-compat/openbsd-compat.h index f34619e4a..bc9888e31 100644 --- a/openbsd-compat/openbsd-compat.h +++ b/openbsd-compat/openbsd-compat.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $Id: openbsd-compat.h,v 1.60 2013/12/07 00:51:54 djm Exp $ */ | 1 | /* $Id: openbsd-compat.h,v 1.61 2014/02/04 00:18:23 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Copyright (c) 1999-2003 Damien Miller. All rights reserved. | 4 | * 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, | |||
246 | u_int8_t *, size_t, unsigned int); | 246 | u_int8_t *, size_t, unsigned int); |
247 | #endif | 247 | #endif |
248 | 248 | ||
249 | #ifndef HAVE_EXPLICIT_BZERO | ||
250 | void explicit_bzero(void *p, size_t n); | ||
251 | #endif | ||
252 | |||
249 | void *xmmap(size_t size); | 253 | void *xmmap(size_t size); |
250 | char *xcrypt(const char *password, const char *salt); | 254 | char *xcrypt(const char *password, const char *salt); |
251 | char *shadow_pw(struct passwd *pw); | 255 | char *shadow_pw(struct passwd *pw); |
diff --git a/openbsd-compat/openssl-compat.c b/openbsd-compat/openssl-compat.c index 60eac4b17..885c121f2 100644 --- a/openbsd-compat/openssl-compat.c +++ b/openbsd-compat/openssl-compat.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $Id: openssl-compat.c,v 1.16 2014/01/17 07:00:41 dtucker Exp $ */ | 1 | /* $Id: openssl-compat.c,v 1.17 2014/02/13 05:38:33 dtucker Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Copyright (c) 2005 Darren Tucker <dtucker@zip.com.au> | 4 | * 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) | |||
96 | } | 96 | } |
97 | #endif | 97 | #endif |
98 | 98 | ||
99 | #ifndef HAVE_EVP_MD_CTX_COPY_EX | ||
100 | int | ||
101 | EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in) | ||
102 | { | ||
103 | return EVP_MD_CTX_copy(out, in); | ||
104 | } | ||
105 | #endif | ||
106 | |||
99 | #ifndef HAVE_BN_IS_PRIME_EX | 107 | #ifndef HAVE_BN_IS_PRIME_EX |
100 | int | 108 | int |
101 | BN_is_prime_ex(const BIGNUM *p, int nchecks, BN_CTX *ctx, void *cb) | 109 | BN_is_prime_ex(const BIGNUM *p, int nchecks, BN_CTX *ctx, void *cb) |
diff --git a/openbsd-compat/openssl-compat.h b/openbsd-compat/openssl-compat.h index 021ea98f5..276b9706d 100644 --- a/openbsd-compat/openssl-compat.h +++ b/openbsd-compat/openssl-compat.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $Id: openssl-compat.h,v 1.25 2014/01/17 06:32:31 dtucker Exp $ */ | 1 | /* $Id: openssl-compat.h,v 1.26 2014/02/13 05:38:33 dtucker Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Copyright (c) 2005 Darren Tucker <dtucker@zip.com.au> | 4 | * Copyright (c) 2005 Darren Tucker <dtucker@zip.com.au> |
@@ -156,6 +156,10 @@ int EVP_DigestInit_ex(EVP_MD_CTX *, const EVP_MD *, void *); | |||
156 | int EVP_DigestFinal_ex(EVP_MD_CTX *, unsigned char *, unsigned int *); | 156 | int EVP_DigestFinal_ex(EVP_MD_CTX *, unsigned char *, unsigned int *); |
157 | # endif | 157 | # endif |
158 | 158 | ||
159 | # ifndef EVP_MD_CTX_COPY_EX | ||
160 | int EVP_MD_CTX_copy_ex(EVP_MD_CTX *, const EVP_MD_CTX *); | ||
161 | # endif | ||
162 | |||
159 | int ssh_EVP_CipherInit(EVP_CIPHER_CTX *, const EVP_CIPHER *, unsigned char *, | 163 | int ssh_EVP_CipherInit(EVP_CIPHER_CTX *, const EVP_CIPHER *, unsigned char *, |
160 | unsigned char *, int); | 164 | unsigned char *, int); |
161 | int ssh_EVP_Cipher(EVP_CIPHER_CTX *, char *, char *, int); | 165 | int ssh_EVP_Cipher(EVP_CIPHER_CTX *, char *, char *, int); |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: packet.c,v 1.191 2013/12/06 13:34:54 markus Exp $ */ | 1 | /* $OpenBSD: packet.c,v 1.192 2014/02/02 03:44:31 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -764,9 +764,9 @@ set_newkeys(int mode) | |||
764 | mac = &active_state->newkeys[mode]->mac; | 764 | mac = &active_state->newkeys[mode]->mac; |
765 | comp = &active_state->newkeys[mode]->comp; | 765 | comp = &active_state->newkeys[mode]->comp; |
766 | mac_clear(mac); | 766 | mac_clear(mac); |
767 | memset(enc->iv, 0, enc->iv_len); | 767 | explicit_bzero(enc->iv, enc->iv_len); |
768 | memset(enc->key, 0, enc->key_len); | 768 | explicit_bzero(enc->key, enc->key_len); |
769 | memset(mac->key, 0, mac->key_len); | 769 | explicit_bzero(mac->key, mac->key_len); |
770 | free(enc->name); | 770 | free(enc->name); |
771 | free(enc->iv); | 771 | free(enc->iv); |
772 | free(enc->key); | 772 | free(enc->key); |
@@ -787,9 +787,9 @@ set_newkeys(int mode) | |||
787 | cipher_init(cc, enc->cipher, enc->key, enc->key_len, | 787 | cipher_init(cc, enc->cipher, enc->key, enc->key_len, |
788 | enc->iv, enc->iv_len, crypt_type); | 788 | enc->iv, enc->iv_len, crypt_type); |
789 | /* Deleting the keys does not gain extra security */ | 789 | /* Deleting the keys does not gain extra security */ |
790 | /* memset(enc->iv, 0, enc->block_size); | 790 | /* explicit_bzero(enc->iv, enc->block_size); |
791 | memset(enc->key, 0, enc->key_len); | 791 | explicit_bzero(enc->key, enc->key_len); |
792 | memset(mac->key, 0, mac->key_len); */ | 792 | explicit_bzero(mac->key, mac->key_len); */ |
793 | if ((comp->type == COMP_ZLIB || | 793 | if ((comp->type == COMP_ZLIB || |
794 | (comp->type == COMP_DELAYED && | 794 | (comp->type == COMP_DELAYED && |
795 | active_state->after_authentication)) && comp->enabled == 0) { | 795 | active_state->after_authentication)) && comp->enabled == 0) { |
@@ -928,7 +928,7 @@ packet_send2_wrapped(void) | |||
928 | } | 928 | } |
929 | } else { | 929 | } else { |
930 | /* clear padding */ | 930 | /* clear padding */ |
931 | memset(cp, 0, padlen); | 931 | explicit_bzero(cp, padlen); |
932 | } | 932 | } |
933 | /* sizeof (packet_len + pad_len + payload + padding) */ | 933 | /* sizeof (packet_len + pad_len + payload + padding) */ |
934 | len = buffer_len(&active_state->outgoing_packet); | 934 | len = buffer_len(&active_state->outgoing_packet); |
diff --git a/readconf.c b/readconf.c index 9c7e73d7d..dc884c9b1 100644 --- a/readconf.c +++ b/readconf.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: readconf.c,v 1.215 2013/12/06 13:39:49 markus Exp $ */ | 1 | /* $OpenBSD: readconf.c,v 1.218 2014/02/23 20:11:36 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -22,6 +22,7 @@ | |||
22 | #include <netinet/in.h> | 22 | #include <netinet/in.h> |
23 | #include <netinet/in_systm.h> | 23 | #include <netinet/in_systm.h> |
24 | #include <netinet/ip.h> | 24 | #include <netinet/ip.h> |
25 | #include <arpa/inet.h> | ||
25 | 26 | ||
26 | #include <ctype.h> | 27 | #include <ctype.h> |
27 | #include <errno.h> | 28 | #include <errno.h> |
@@ -144,7 +145,7 @@ typedef enum { | |||
144 | oSendEnv, oControlPath, oControlMaster, oControlPersist, | 145 | oSendEnv, oControlPath, oControlMaster, oControlPersist, |
145 | oHashKnownHosts, | 146 | oHashKnownHosts, |
146 | oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand, | 147 | oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand, |
147 | oVisualHostKey, oUseRoaming, oZeroKnowledgePasswordAuthentication, | 148 | oVisualHostKey, oUseRoaming, |
148 | oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass, | 149 | oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass, |
149 | oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots, | 150 | oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots, |
150 | oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs, | 151 | oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs, |
@@ -251,12 +252,6 @@ static struct { | |||
251 | { "permitlocalcommand", oPermitLocalCommand }, | 252 | { "permitlocalcommand", oPermitLocalCommand }, |
252 | { "visualhostkey", oVisualHostKey }, | 253 | { "visualhostkey", oVisualHostKey }, |
253 | { "useroaming", oUseRoaming }, | 254 | { "useroaming", oUseRoaming }, |
254 | #ifdef JPAKE | ||
255 | { "zeroknowledgepasswordauthentication", | ||
256 | oZeroKnowledgePasswordAuthentication }, | ||
257 | #else | ||
258 | { "zeroknowledgepasswordauthentication", oUnsupported }, | ||
259 | #endif | ||
260 | { "kexalgorithms", oKexAlgorithms }, | 255 | { "kexalgorithms", oKexAlgorithms }, |
261 | { "ipqos", oIPQoS }, | 256 | { "ipqos", oIPQoS }, |
262 | { "requesttty", oRequestTTY }, | 257 | { "requesttty", oRequestTTY }, |
@@ -542,16 +537,27 @@ match_cfg_line(Options *options, char **condition, struct passwd *pw, | |||
542 | "r", ruser, | 537 | "r", ruser, |
543 | "u", pw->pw_name, | 538 | "u", pw->pw_name, |
544 | (char *)NULL); | 539 | (char *)NULL); |
545 | r = execute_in_shell(cmd); | 540 | if (result != 1) { |
546 | if (r == -1) { | 541 | /* skip execution if prior predicate failed */ |
547 | fatal("%.200s line %d: match exec '%.100s' " | 542 | debug("%.200s line %d: skipped exec \"%.100s\"", |
548 | "error", filename, linenum, cmd); | ||
549 | } else if (r == 0) { | ||
550 | debug("%.200s line %d: matched " | ||
551 | "'exec \"%.100s\"' ", | ||
552 | filename, linenum, cmd); | 543 | filename, linenum, cmd); |
553 | } else | 544 | } else { |
554 | result = 0; | 545 | r = execute_in_shell(cmd); |
546 | if (r == -1) { | ||
547 | fatal("%.200s line %d: match exec " | ||
548 | "'%.100s' error", filename, | ||
549 | linenum, cmd); | ||
550 | } else if (r == 0) { | ||
551 | debug("%.200s line %d: matched " | ||
552 | "'exec \"%.100s\"'", filename, | ||
553 | linenum, cmd); | ||
554 | } else { | ||
555 | debug("%.200s line %d: no match " | ||
556 | "'exec \"%.100s\"'", filename, | ||
557 | linenum, cmd); | ||
558 | result = 0; | ||
559 | } | ||
560 | } | ||
555 | free(cmd); | 561 | free(cmd); |
556 | } else { | 562 | } else { |
557 | error("Unsupported Match attribute %s", attrib); | 563 | error("Unsupported Match attribute %s", attrib); |
@@ -803,10 +809,6 @@ parse_time: | |||
803 | intptr = &options->password_authentication; | 809 | intptr = &options->password_authentication; |
804 | goto parse_flag; | 810 | goto parse_flag; |
805 | 811 | ||
806 | case oZeroKnowledgePasswordAuthentication: | ||
807 | intptr = &options->zero_knowledge_password_authentication; | ||
808 | goto parse_flag; | ||
809 | |||
810 | case oKbdInteractiveAuthentication: | 812 | case oKbdInteractiveAuthentication: |
811 | intptr = &options->kbd_interactive_authentication; | 813 | intptr = &options->kbd_interactive_authentication; |
812 | goto parse_flag; | 814 | goto parse_flag; |
@@ -1465,6 +1467,13 @@ read_config_file(const char *filename, struct passwd *pw, const char *host, | |||
1465 | return 1; | 1467 | return 1; |
1466 | } | 1468 | } |
1467 | 1469 | ||
1470 | /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */ | ||
1471 | int | ||
1472 | option_clear_or_none(const char *o) | ||
1473 | { | ||
1474 | return o == NULL || strcasecmp(o, "none") == 0; | ||
1475 | } | ||
1476 | |||
1468 | /* | 1477 | /* |
1469 | * Initializes options to special values that indicate that they have not yet | 1478 | * Initializes options to special values that indicate that they have not yet |
1470 | * been set. Read_config_file will only set options with this value. Options | 1479 | * been set. Read_config_file will only set options with this value. Options |
@@ -1549,7 +1558,6 @@ initialize_options(Options * options) | |||
1549 | options->permit_local_command = -1; | 1558 | options->permit_local_command = -1; |
1550 | options->use_roaming = -1; | 1559 | options->use_roaming = -1; |
1551 | options->visual_host_key = -1; | 1560 | options->visual_host_key = -1; |
1552 | options->zero_knowledge_password_authentication = -1; | ||
1553 | options->ip_qos_interactive = -1; | 1561 | options->ip_qos_interactive = -1; |
1554 | options->ip_qos_bulk = -1; | 1562 | options->ip_qos_bulk = -1; |
1555 | options->request_tty = -1; | 1563 | options->request_tty = -1; |
@@ -1563,10 +1571,24 @@ initialize_options(Options * options) | |||
1563 | } | 1571 | } |
1564 | 1572 | ||
1565 | /* | 1573 | /* |
1574 | * A petite version of fill_default_options() that just fills the options | ||
1575 | * needed for hostname canonicalization to proceed. | ||
1576 | */ | ||
1577 | void | ||
1578 | fill_default_options_for_canonicalization(Options *options) | ||
1579 | { | ||
1580 | if (options->canonicalize_max_dots == -1) | ||
1581 | options->canonicalize_max_dots = 1; | ||
1582 | if (options->canonicalize_fallback_local == -1) | ||
1583 | options->canonicalize_fallback_local = 1; | ||
1584 | if (options->canonicalize_hostname == -1) | ||
1585 | options->canonicalize_hostname = SSH_CANONICALISE_NO; | ||
1586 | } | ||
1587 | |||
1588 | /* | ||
1566 | * Called after processing other sources of option data, this fills those | 1589 | * Called after processing other sources of option data, this fills those |
1567 | * options for which no value has been specified with their default values. | 1590 | * options for which no value has been specified with their default values. |
1568 | */ | 1591 | */ |
1569 | |||
1570 | void | 1592 | void |
1571 | fill_default_options(Options * options) | 1593 | fill_default_options(Options * options) |
1572 | { | 1594 | { |
@@ -1705,8 +1727,6 @@ fill_default_options(Options * options) | |||
1705 | options->use_roaming = 1; | 1727 | options->use_roaming = 1; |
1706 | if (options->visual_host_key == -1) | 1728 | if (options->visual_host_key == -1) |
1707 | options->visual_host_key = 0; | 1729 | options->visual_host_key = 0; |
1708 | if (options->zero_knowledge_password_authentication == -1) | ||
1709 | options->zero_knowledge_password_authentication = 0; | ||
1710 | if (options->ip_qos_interactive == -1) | 1730 | if (options->ip_qos_interactive == -1) |
1711 | options->ip_qos_interactive = IPTOS_LOWDELAY; | 1731 | options->ip_qos_interactive = IPTOS_LOWDELAY; |
1712 | if (options->ip_qos_bulk == -1) | 1732 | if (options->ip_qos_bulk == -1) |
@@ -1723,7 +1743,7 @@ fill_default_options(Options * options) | |||
1723 | options->canonicalize_hostname = SSH_CANONICALISE_NO; | 1743 | options->canonicalize_hostname = SSH_CANONICALISE_NO; |
1724 | #define CLEAR_ON_NONE(v) \ | 1744 | #define CLEAR_ON_NONE(v) \ |
1725 | do { \ | 1745 | do { \ |
1726 | if (v != NULL && strcasecmp(v, "none") == 0) { \ | 1746 | if (option_clear_or_none(v)) { \ |
1727 | free(v); \ | 1747 | free(v); \ |
1728 | v = NULL; \ | 1748 | v = NULL; \ |
1729 | } \ | 1749 | } \ |
diff --git a/readconf.h b/readconf.h index 2d7ea9fc4..75e3f8f7a 100644 --- a/readconf.h +++ b/readconf.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: readconf.h,v 1.99 2013/10/16 22:49:38 djm Exp $ */ | 1 | /* $OpenBSD: readconf.h,v 1.101 2014/02/23 20:11:36 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
@@ -59,7 +59,6 @@ typedef struct { | |||
59 | * authentication. */ | 59 | * authentication. */ |
60 | int kbd_interactive_authentication; /* Try keyboard-interactive auth. */ | 60 | int kbd_interactive_authentication; /* Try keyboard-interactive auth. */ |
61 | char *kbd_interactive_devices; /* Keyboard-interactive auth devices. */ | 61 | char *kbd_interactive_devices; /* Keyboard-interactive auth devices. */ |
62 | int zero_knowledge_password_authentication; /* Try jpake */ | ||
63 | int batch_mode; /* Batch mode: do not ask for passwords. */ | 62 | int batch_mode; /* Batch mode: do not ask for passwords. */ |
64 | int check_host_ip; /* Also keep track of keys for IP address */ | 63 | int check_host_ip; /* Also keep track of keys for IP address */ |
65 | int strict_host_key_checking; /* Strict host key checking. */ | 64 | int strict_host_key_checking; /* Strict host key checking. */ |
@@ -177,12 +176,14 @@ typedef struct { | |||
177 | 176 | ||
178 | void initialize_options(Options *); | 177 | void initialize_options(Options *); |
179 | void fill_default_options(Options *); | 178 | void fill_default_options(Options *); |
179 | void fill_default_options_for_canonicalization(Options *); | ||
180 | int process_config_line(Options *, struct passwd *, const char *, char *, | 180 | int process_config_line(Options *, struct passwd *, const char *, char *, |
181 | const char *, int, int *, int); | 181 | const char *, int, int *, int); |
182 | int read_config_file(const char *, struct passwd *, const char *, | 182 | int read_config_file(const char *, struct passwd *, const char *, |
183 | Options *, int); | 183 | Options *, int); |
184 | int parse_forward(Forward *, const char *, int, int); | 184 | int parse_forward(Forward *, const char *, int, int); |
185 | int default_ssh_port(void); | 185 | int default_ssh_port(void); |
186 | int option_clear_or_none(const char *); | ||
186 | 187 | ||
187 | void add_local_forward(Options *, const Forward *); | 188 | void add_local_forward(Options *, const Forward *); |
188 | void add_remote_forward(Options *, const Forward *); | 189 | void add_remote_forward(Options *, const Forward *); |
diff --git a/readpass.c b/readpass.c index e37d31158..869d86425 100644 --- a/readpass.c +++ b/readpass.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: readpass.c,v 1.49 2013/05/17 00:13:14 djm Exp $ */ | 1 | /* $OpenBSD: readpass.c,v 1.50 2014/02/02 03:44:31 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2001 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2001 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -99,13 +99,13 @@ ssh_askpass(char *askpass, const char *msg) | |||
99 | break; | 99 | break; |
100 | signal(SIGCHLD, osigchld); | 100 | signal(SIGCHLD, osigchld); |
101 | if (ret == -1 || !WIFEXITED(status) || WEXITSTATUS(status) != 0) { | 101 | if (ret == -1 || !WIFEXITED(status) || WEXITSTATUS(status) != 0) { |
102 | memset(buf, 0, sizeof(buf)); | 102 | explicit_bzero(buf, sizeof(buf)); |
103 | return NULL; | 103 | return NULL; |
104 | } | 104 | } |
105 | 105 | ||
106 | buf[strcspn(buf, "\r\n")] = '\0'; | 106 | buf[strcspn(buf, "\r\n")] = '\0'; |
107 | pass = xstrdup(buf); | 107 | pass = xstrdup(buf); |
108 | memset(buf, 0, sizeof(buf)); | 108 | explicit_bzero(buf, sizeof(buf)); |
109 | return pass; | 109 | return pass; |
110 | } | 110 | } |
111 | 111 | ||
@@ -162,7 +162,7 @@ read_passphrase(const char *prompt, int flags) | |||
162 | } | 162 | } |
163 | 163 | ||
164 | ret = xstrdup(buf); | 164 | ret = xstrdup(buf); |
165 | memset(buf, 'x', sizeof buf); | 165 | explicit_bzero(buf, sizeof(buf)); |
166 | return ret; | 166 | return ret; |
167 | } | 167 | } |
168 | 168 | ||
diff --git a/regress/Makefile b/regress/Makefile index 0c66b1774..6e3b8d634 100644 --- a/regress/Makefile +++ b/regress/Makefile | |||
@@ -1,4 +1,4 @@ | |||
1 | # $OpenBSD: Makefile,v 1.67 2013/12/06 13:52:46 markus Exp $ | 1 | # $OpenBSD: Makefile,v 1.68 2014/01/25 04:35:32 dtucker Exp $ |
2 | 2 | ||
3 | REGRESS_TARGETS= t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t-exec | 3 | REGRESS_TARGETS= t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t-exec |
4 | tests: $(REGRESS_TARGETS) | 4 | tests: $(REGRESS_TARGETS) |
@@ -65,6 +65,7 @@ LTESTS= connect \ | |||
65 | forward-control \ | 65 | forward-control \ |
66 | integrity \ | 66 | integrity \ |
67 | krl | 67 | krl |
68 | # dhgex \ | ||
68 | 69 | ||
69 | INTEROP_TESTS= putty-transfer putty-ciphers putty-kex conch-ciphers | 70 | INTEROP_TESTS= putty-transfer putty-ciphers putty-kex conch-ciphers |
70 | #INTEROP_TESTS+=ssh-com ssh-com-client ssh-com-keygen ssh-com-sftp | 71 | #INTEROP_TESTS+=ssh-com ssh-com-client ssh-com-keygen ssh-com-sftp |
diff --git a/regress/agent-ptrace.sh b/regress/agent-ptrace.sh index ae150641f..1912ca8f9 100644 --- a/regress/agent-ptrace.sh +++ b/regress/agent-ptrace.sh | |||
@@ -1,4 +1,4 @@ | |||
1 | # $OpenBSD: agent-ptrace.sh,v 1.1 2002/12/09 15:38:30 markus Exp $ | 1 | # $OpenBSD: agent-ptrace.sh,v 1.2 2014/02/27 21:21:25 djm Exp $ |
2 | # Placed in the Public Domain. | 2 | # Placed in the Public Domain. |
3 | 3 | ||
4 | tid="disallow agent ptrace attach" | 4 | tid="disallow agent ptrace attach" |
diff --git a/regress/agent.sh b/regress/agent.sh index cf1a45fe0..caad3c88e 100644 --- a/regress/agent.sh +++ b/regress/agent.sh | |||
@@ -1,4 +1,4 @@ | |||
1 | # $OpenBSD: agent.sh,v 1.9 2013/12/06 13:52:46 markus Exp $ | 1 | # $OpenBSD: agent.sh,v 1.10 2014/02/27 21:21:25 djm Exp $ |
2 | # Placed in the Public Domain. | 2 | # Placed in the Public Domain. |
3 | 3 | ||
4 | tid="simple agent test" | 4 | tid="simple agent test" |
diff --git a/regress/cert-hostkey.sh b/regress/cert-hostkey.sh index a1318cd53..1d9e0ed8e 100644 --- a/regress/cert-hostkey.sh +++ b/regress/cert-hostkey.sh | |||
@@ -1,4 +1,4 @@ | |||
1 | # $OpenBSD: cert-hostkey.sh,v 1.8 2013/12/06 13:52:46 markus Exp $ | 1 | # $OpenBSD: cert-hostkey.sh,v 1.9 2014/01/26 10:22:10 djm Exp $ |
2 | # Placed in the Public Domain. | 2 | # Placed in the Public Domain. |
3 | 3 | ||
4 | tid="certified host keys" | 4 | tid="certified host keys" |
diff --git a/regress/dhgex.sh b/regress/dhgex.sh new file mode 100644 index 000000000..4c1a3d83c --- /dev/null +++ b/regress/dhgex.sh | |||
@@ -0,0 +1,54 @@ | |||
1 | # $OpenBSD: dhgex.sh,v 1.1 2014/01/25 04:35:32 dtucker Exp $ | ||
2 | # Placed in the Public Domain. | ||
3 | |||
4 | tid="dhgex" | ||
5 | |||
6 | LOG=${TEST_SSH_LOGFILE} | ||
7 | rm -f ${LOG} | ||
8 | |||
9 | kexs=`${SSH} -Q kex | grep diffie-hellman-group-exchange` | ||
10 | |||
11 | ssh_test_dhgex() | ||
12 | { | ||
13 | bits="$1"; shift | ||
14 | cipher="$1"; shift | ||
15 | kex="$1"; shift | ||
16 | |||
17 | rm -f ${LOG} | ||
18 | opts="-oKexAlgorithms=$kex -oCiphers=$cipher" | ||
19 | groupsz="1024<$bits<8192" | ||
20 | verbose "$tid bits $bits $kex $cipher" | ||
21 | ${SSH} ${opts} $@ -vvv -F ${OBJ}/ssh_proxy somehost true | ||
22 | if [ $? -ne 0 ]; then | ||
23 | fail "ssh failed ($@)" | ||
24 | fi | ||
25 | # check what we request | ||
26 | grep "SSH2_MSG_KEX_DH_GEX_REQUEST($groupsz) sent" ${LOG} >/dev/null | ||
27 | if [ $? != 0 ]; then | ||
28 | got=`egrep "SSH2_MSG_KEX_DH_GEX_REQUEST(.*) sent" ${LOG}` | ||
29 | fail "$tid unexpected GEX sizes, expected $groupsz, got $got" | ||
30 | fi | ||
31 | # check what we got (depends on contents of system moduli file) | ||
32 | gotbits="`awk '/bits set:/{print $4}' ${LOG} | head -1 | cut -f2 -d/`" | ||
33 | if [ "$gotbits" -lt "$bits" ]; then | ||
34 | fatal "$tid expected $bits bit group, got $gotbits" | ||
35 | fi | ||
36 | } | ||
37 | |||
38 | check() | ||
39 | { | ||
40 | bits="$1"; shift | ||
41 | |||
42 | for c in $@; do | ||
43 | for k in $kexs; do | ||
44 | ssh_test_dhgex $bits $c $k | ||
45 | done | ||
46 | done | ||
47 | } | ||
48 | |||
49 | #check 2048 3des-cbc | ||
50 | check 3072 `${SSH} -Q cipher | grep 128` | ||
51 | check 3072 arcfour blowfish-cbc | ||
52 | check 7680 `${SSH} -Q cipher | grep 192` | ||
53 | check 8192 `${SSH} -Q cipher | grep 256` | ||
54 | check 8192 rijndael-cbc@lysator.liu.se chacha20-poly1305@openssh.com | ||
diff --git a/regress/host-expand.sh b/regress/host-expand.sh index a0188363d..6cc0e6055 100644 --- a/regress/host-expand.sh +++ b/regress/host-expand.sh | |||
@@ -1,3 +1,4 @@ | |||
1 | # $OpenBSD: host-expand.sh,v 1.3 2014/02/27 23:17:41 djm Exp $ | ||
1 | # Placed in the Public Domain. | 2 | # Placed in the Public Domain. |
2 | 3 | ||
3 | tid="expand %h and %n" | 4 | tid="expand %h and %n" |
diff --git a/regress/login-timeout.sh b/regress/login-timeout.sh index d73923b9c..d9b48f391 100644 --- a/regress/login-timeout.sh +++ b/regress/login-timeout.sh | |||
@@ -1,9 +1,11 @@ | |||
1 | # $OpenBSD: login-timeout.sh,v 1.5 2013/05/17 10:23:52 dtucker Exp $ | 1 | # $OpenBSD: login-timeout.sh,v 1.6 2014/02/27 20:04:16 djm Exp $ |
2 | # Placed in the Public Domain. | 2 | # Placed in the Public Domain. |
3 | 3 | ||
4 | tid="connect after login grace timeout" | 4 | tid="connect after login grace timeout" |
5 | 5 | ||
6 | trace "test login grace with privsep" | 6 | trace "test login grace with privsep" |
7 | cp $OBJ/sshd_config $OBJ/sshd_config.orig | ||
8 | grep -vi LoginGraceTime $OBJ/sshd_config.orig > $OBJ/sshd_config | ||
7 | echo "LoginGraceTime 10s" >> $OBJ/sshd_config | 9 | echo "LoginGraceTime 10s" >> $OBJ/sshd_config |
8 | echo "MaxStartups 1" >> $OBJ/sshd_config | 10 | echo "MaxStartups 1" >> $OBJ/sshd_config |
9 | start_sshd | 11 | start_sshd |
diff --git a/regress/scp-ssh-wrapper.sh b/regress/scp-ssh-wrapper.sh index c63bc2bc1..59f1ff63e 100644 --- a/regress/scp-ssh-wrapper.sh +++ b/regress/scp-ssh-wrapper.sh | |||
@@ -1,5 +1,5 @@ | |||
1 | #!/bin/sh | 1 | #!/bin/sh |
2 | # $OpenBSD: scp-ssh-wrapper.sh,v 1.2 2005/12/14 04:36:39 dtucker Exp $ | 2 | # $OpenBSD: scp-ssh-wrapper.sh,v 1.3 2014/01/26 10:49:17 djm Exp $ |
3 | # Placed in the Public Domain. | 3 | # Placed in the Public Domain. |
4 | 4 | ||
5 | printname () { | 5 | printname () { |
diff --git a/regress/scp.sh b/regress/scp.sh index c2da2a862..57cc77066 100644 --- a/regress/scp.sh +++ b/regress/scp.sh | |||
@@ -1,4 +1,4 @@ | |||
1 | # $OpenBSD: scp.sh,v 1.9 2013/05/17 10:35:43 dtucker Exp $ | 1 | # $OpenBSD: scp.sh,v 1.10 2014/01/26 10:49:17 djm Exp $ |
2 | # Placed in the Public Domain. | 2 | # Placed in the Public Domain. |
3 | 3 | ||
4 | tid="scp" | 4 | tid="scp" |
diff --git a/regress/setuid-allowed.c b/regress/setuid-allowed.c index 37b7dc8ad..676d2661c 100644 --- a/regress/setuid-allowed.c +++ b/regress/setuid-allowed.c | |||
@@ -23,6 +23,7 @@ | |||
23 | # include <sys/statvfs.h> | 23 | # include <sys/statvfs.h> |
24 | #endif | 24 | #endif |
25 | #include <stdio.h> | 25 | #include <stdio.h> |
26 | #include <string.h> | ||
26 | #include <errno.h> | 27 | #include <errno.h> |
27 | 28 | ||
28 | void | 29 | void |
diff --git a/regress/sftp-chroot.sh b/regress/sftp-chroot.sh index 03b9bc6d7..23f7456e8 100644 --- a/regress/sftp-chroot.sh +++ b/regress/sftp-chroot.sh | |||
@@ -1,4 +1,4 @@ | |||
1 | # $OpenBSD: sftp-chroot.sh,v 1.2 2013/05/17 04:29:14 dtucker Exp $ | 1 | # $OpenBSD: sftp-chroot.sh,v 1.4 2014/01/20 00:00:30 dtucker Exp $ |
2 | # Placed in the Public Domain. | 2 | # Placed in the Public Domain. |
3 | 3 | ||
4 | tid="sftp in chroot" | 4 | tid="sftp in chroot" |
@@ -18,7 +18,8 @@ $SUDO sh -c "echo mekmitastdigoat > $PRIVDATA" || \ | |||
18 | start_sshd -oChrootDirectory=$CHROOT -oForceCommand="internal-sftp -d /" | 18 | start_sshd -oChrootDirectory=$CHROOT -oForceCommand="internal-sftp -d /" |
19 | 19 | ||
20 | verbose "test $tid: get" | 20 | verbose "test $tid: get" |
21 | ${SFTP} -qS "$SSH" -F $OBJ/ssh_config host:/${FILENAME} $COPY || \ | 21 | ${SFTP} -S "$SSH" -F $OBJ/ssh_config host:/${FILENAME} $COPY \ |
22 | >>$TEST_REGRESS_LOGFILE 2>&1 || \ | ||
22 | fatal "Fetch ${FILENAME} failed" | 23 | fatal "Fetch ${FILENAME} failed" |
23 | cmp $PRIVDATA $COPY || fail "$PRIVDATA $COPY differ" | 24 | cmp $PRIVDATA $COPY || fail "$PRIVDATA $COPY differ" |
24 | 25 | ||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: rsa.c,v 1.30 2013/05/17 00:13:14 djm Exp $ */ | 1 | /* $OpenBSD: rsa.c,v 1.31 2014/02/02 03:44:31 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -94,8 +94,8 @@ rsa_public_encrypt(BIGNUM *out, BIGNUM *in, RSA *key) | |||
94 | if (BN_bin2bn(outbuf, len, out) == NULL) | 94 | if (BN_bin2bn(outbuf, len, out) == NULL) |
95 | fatal("rsa_public_encrypt: BN_bin2bn failed"); | 95 | fatal("rsa_public_encrypt: BN_bin2bn failed"); |
96 | 96 | ||
97 | memset(outbuf, 0, olen); | 97 | explicit_bzero(outbuf, olen); |
98 | memset(inbuf, 0, ilen); | 98 | explicit_bzero(inbuf, ilen); |
99 | free(outbuf); | 99 | free(outbuf); |
100 | free(inbuf); | 100 | free(inbuf); |
101 | } | 101 | } |
@@ -120,8 +120,8 @@ rsa_private_decrypt(BIGNUM *out, BIGNUM *in, RSA *key) | |||
120 | if (BN_bin2bn(outbuf, len, out) == NULL) | 120 | if (BN_bin2bn(outbuf, len, out) == NULL) |
121 | fatal("rsa_private_decrypt: BN_bin2bn failed"); | 121 | fatal("rsa_private_decrypt: BN_bin2bn failed"); |
122 | } | 122 | } |
123 | memset(outbuf, 0, olen); | 123 | explicit_bzero(outbuf, olen); |
124 | memset(inbuf, 0, ilen); | 124 | explicit_bzero(inbuf, ilen); |
125 | free(outbuf); | 125 | free(outbuf); |
126 | free(inbuf); | 126 | free(inbuf); |
127 | return len; | 127 | return len; |
diff --git a/sandbox-capsicum.c b/sandbox-capsicum.c index ee2a7e79e..655f0d217 100644 --- a/sandbox-capsicum.c +++ b/sandbox-capsicum.c | |||
@@ -94,10 +94,12 @@ ssh_sandbox_child(struct ssh_sandbox *box) | |||
94 | fatal("can't limit stderr: %m"); | 94 | fatal("can't limit stderr: %m"); |
95 | 95 | ||
96 | cap_rights_init(&rights, CAP_READ, CAP_WRITE); | 96 | cap_rights_init(&rights, CAP_READ, CAP_WRITE); |
97 | if (cap_rights_limit(box->monitor->m_recvfd, &rights) == -1) | 97 | if (cap_rights_limit(box->monitor->m_recvfd, &rights) < 0 && |
98 | errno != ENOSYS) | ||
98 | fatal("%s: failed to limit the network socket", __func__); | 99 | fatal("%s: failed to limit the network socket", __func__); |
99 | cap_rights_init(&rights, CAP_WRITE); | 100 | cap_rights_init(&rights, CAP_WRITE); |
100 | if (cap_rights_limit(box->monitor->m_log_sendfd, &rights) == -1) | 101 | if (cap_rights_limit(box->monitor->m_log_sendfd, &rights) < 0 && |
102 | errno != ENOSYS) | ||
101 | fatal("%s: failed to limit the logging socket", __func__); | 103 | fatal("%s: failed to limit the logging socket", __func__); |
102 | if (cap_enter() < 0 && errno != ENOSYS) | 104 | if (cap_enter() < 0 && errno != ENOSYS) |
103 | fatal("%s: failed to enter capability mode", __func__); | 105 | fatal("%s: failed to enter capability mode", __func__); |
diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c index 2f73067e1..c0c17c2fc 100644 --- a/sandbox-seccomp-filter.c +++ b/sandbox-seccomp-filter.c | |||
@@ -98,6 +98,9 @@ static const struct sock_filter preauth_insns[] = { | |||
98 | SC_ALLOW(read), | 98 | SC_ALLOW(read), |
99 | SC_ALLOW(write), | 99 | SC_ALLOW(write), |
100 | SC_ALLOW(close), | 100 | SC_ALLOW(close), |
101 | #ifdef __NR_shutdown /* not defined on archs that go via socketcall(2) */ | ||
102 | SC_ALLOW(shutdown), | ||
103 | #endif | ||
101 | SC_ALLOW(brk), | 104 | SC_ALLOW(brk), |
102 | SC_ALLOW(poll), | 105 | SC_ALLOW(poll), |
103 | #ifdef __NR__newselect | 106 | #ifdef __NR__newselect |
diff --git a/sandbox-systrace.c b/sandbox-systrace.c index 53fbd47cb..6706c9a80 100644 --- a/sandbox-systrace.c +++ b/sandbox-systrace.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sandbox-systrace.c,v 1.7 2013/06/01 13:15:52 dtucker Exp $ */ | 1 | /* $OpenBSD: sandbox-systrace.c,v 1.9 2014/01/31 16:39:19 tedu Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2011 Damien Miller <djm@mindrot.org> | 3 | * Copyright (c) 2011 Damien Miller <djm@mindrot.org> |
4 | * | 4 | * |
@@ -66,6 +66,7 @@ static const struct sandbox_policy preauth_policy[] = { | |||
66 | { SYS_munmap, SYSTR_POLICY_PERMIT }, | 66 | { SYS_munmap, SYSTR_POLICY_PERMIT }, |
67 | { SYS_read, SYSTR_POLICY_PERMIT }, | 67 | { SYS_read, SYSTR_POLICY_PERMIT }, |
68 | { SYS_select, SYSTR_POLICY_PERMIT }, | 68 | { SYS_select, SYSTR_POLICY_PERMIT }, |
69 | { SYS_shutdown, SYSTR_POLICY_PERMIT }, | ||
69 | { SYS_sigprocmask, SYSTR_POLICY_PERMIT }, | 70 | { SYS_sigprocmask, SYSTR_POLICY_PERMIT }, |
70 | { SYS_write, SYSTR_POLICY_PERMIT }, | 71 | { SYS_write, SYSTR_POLICY_PERMIT }, |
71 | { -1, -1 } | 72 | { -1, -1 } |
@@ -141,7 +142,7 @@ ssh_sandbox_parent(struct ssh_sandbox *box, pid_t child_pid, | |||
141 | box->systrace_fd, child_pid, strerror(errno)); | 142 | box->systrace_fd, child_pid, strerror(errno)); |
142 | 143 | ||
143 | /* Allocate and assign policy */ | 144 | /* Allocate and assign policy */ |
144 | bzero(&policy, sizeof(policy)); | 145 | memset(&policy, 0, sizeof(policy)); |
145 | policy.strp_op = SYSTR_POLICY_NEW; | 146 | policy.strp_op = SYSTR_POLICY_NEW; |
146 | policy.strp_maxents = SYS_MAXSYSCALL; | 147 | policy.strp_maxents = SYS_MAXSYSCALL; |
147 | if (ioctl(box->systrace_fd, STRIOCPOLICY, &policy) == -1) | 148 | if (ioctl(box->systrace_fd, STRIOCPOLICY, &policy) == -1) |
diff --git a/schnorr.c b/schnorr.c deleted file mode 100644 index aa3a57770..000000000 --- a/schnorr.c +++ /dev/null | |||
@@ -1,668 +0,0 @@ | |||
1 | /* $OpenBSD: schnorr.c,v 1.9 2014/01/09 23:20:00 djm Exp $ */ | ||
2 | /* | ||
3 | * Copyright (c) 2008 Damien Miller. All rights reserved. | ||
4 | * | ||
5 | * Permission to use, copy, modify, and distribute this software for any | ||
6 | * purpose with or without fee is hereby granted, provided that the above | ||
7 | * copyright notice and this permission notice appear in all copies. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
10 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
11 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
12 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
13 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
16 | */ | ||
17 | |||
18 | /* | ||
19 | * Implementation of Schnorr signatures / zero-knowledge proofs, based on | ||
20 | * description in: | ||
21 | * | ||
22 | * F. Hao, P. Ryan, "Password Authenticated Key Exchange by Juggling", | ||
23 | * 16th Workshop on Security Protocols, Cambridge, April 2008 | ||
24 | * | ||
25 | * http://grouper.ieee.org/groups/1363/Research/contributions/hao-ryan-2008.pdf | ||
26 | */ | ||
27 | |||
28 | #include "includes.h" | ||
29 | |||
30 | #include <sys/types.h> | ||
31 | |||
32 | #include <string.h> | ||
33 | #include <stdarg.h> | ||
34 | #include <stdio.h> | ||
35 | |||
36 | #include <openssl/evp.h> | ||
37 | #include <openssl/bn.h> | ||
38 | |||
39 | #include "xmalloc.h" | ||
40 | #include "buffer.h" | ||
41 | #include "log.h" | ||
42 | |||
43 | #include "schnorr.h" | ||
44 | #include "digest.h" | ||
45 | |||
46 | #include "openbsd-compat/openssl-compat.h" | ||
47 | |||
48 | /* #define SCHNORR_DEBUG */ /* Privacy-violating debugging */ | ||
49 | /* #define SCHNORR_MAIN */ /* Include main() selftest */ | ||
50 | |||
51 | #ifndef SCHNORR_DEBUG | ||
52 | # define SCHNORR_DEBUG_BN(a) | ||
53 | # define SCHNORR_DEBUG_BUF(a) | ||
54 | #else | ||
55 | # define SCHNORR_DEBUG_BN(a) debug3_bn a | ||
56 | # define SCHNORR_DEBUG_BUF(a) debug3_buf a | ||
57 | #endif /* SCHNORR_DEBUG */ | ||
58 | |||
59 | /* | ||
60 | * Calculate hash component of Schnorr signature H(g || g^v || g^x || id) | ||
61 | * using the hash function defined by "hash_alg". Returns signature as | ||
62 | * bignum or NULL on error. | ||
63 | */ | ||
64 | static BIGNUM * | ||
65 | schnorr_hash(const BIGNUM *p, const BIGNUM *q, const BIGNUM *g, | ||
66 | int hash_alg, const BIGNUM *g_v, const BIGNUM *g_x, | ||
67 | const u_char *id, u_int idlen) | ||
68 | { | ||
69 | u_char *digest; | ||
70 | u_int digest_len; | ||
71 | BIGNUM *h; | ||
72 | Buffer b; | ||
73 | int success = -1; | ||
74 | |||
75 | if ((h = BN_new()) == NULL) { | ||
76 | error("%s: BN_new", __func__); | ||
77 | return NULL; | ||
78 | } | ||
79 | |||
80 | buffer_init(&b); | ||
81 | |||
82 | /* h = H(g || p || q || g^v || g^x || id) */ | ||
83 | buffer_put_bignum2(&b, g); | ||
84 | buffer_put_bignum2(&b, p); | ||
85 | buffer_put_bignum2(&b, q); | ||
86 | buffer_put_bignum2(&b, g_v); | ||
87 | buffer_put_bignum2(&b, g_x); | ||
88 | buffer_put_string(&b, id, idlen); | ||
89 | |||
90 | SCHNORR_DEBUG_BUF((buffer_ptr(&b), buffer_len(&b), | ||
91 | "%s: hashblob", __func__)); | ||
92 | if (hash_buffer(buffer_ptr(&b), buffer_len(&b), hash_alg, | ||
93 | &digest, &digest_len) != 0) { | ||
94 | error("%s: hash_buffer", __func__); | ||
95 | goto out; | ||
96 | } | ||
97 | if (BN_bin2bn(digest, (int)digest_len, h) == NULL) { | ||
98 | error("%s: BN_bin2bn", __func__); | ||
99 | goto out; | ||
100 | } | ||
101 | success = 0; | ||
102 | SCHNORR_DEBUG_BN((h, "%s: h = ", __func__)); | ||
103 | out: | ||
104 | buffer_free(&b); | ||
105 | bzero(digest, digest_len); | ||
106 | free(digest); | ||
107 | digest_len = 0; | ||
108 | if (success == 0) | ||
109 | return h; | ||
110 | BN_clear_free(h); | ||
111 | return NULL; | ||
112 | } | ||
113 | |||
114 | /* | ||
115 | * Generate Schnorr signature to prove knowledge of private value 'x' used | ||
116 | * in public exponent g^x, under group defined by 'grp_p', 'grp_q' and 'grp_g' | ||
117 | * using the hash function "hash_alg". | ||
118 | * 'idlen' bytes from 'id' will be included in the signature hash as an anti- | ||
119 | * replay salt. | ||
120 | * | ||
121 | * On success, 0 is returned. The signature values are returned as *e_p | ||
122 | * (g^v mod p) and *r_p (v - xh mod q). The caller must free these values. | ||
123 | * On failure, -1 is returned. | ||
124 | */ | ||
125 | int | ||
126 | schnorr_sign(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g, | ||
127 | int hash_alg, const BIGNUM *x, const BIGNUM *g_x, | ||
128 | const u_char *id, u_int idlen, BIGNUM **r_p, BIGNUM **e_p) | ||
129 | { | ||
130 | int success = -1; | ||
131 | BIGNUM *h, *tmp, *v, *g_v, *r; | ||
132 | BN_CTX *bn_ctx; | ||
133 | |||
134 | SCHNORR_DEBUG_BN((x, "%s: x = ", __func__)); | ||
135 | SCHNORR_DEBUG_BN((g_x, "%s: g_x = ", __func__)); | ||
136 | |||
137 | /* Avoid degenerate cases: g^0 yields a spoofable signature */ | ||
138 | if (BN_cmp(g_x, BN_value_one()) <= 0) { | ||
139 | error("%s: g_x < 1", __func__); | ||
140 | return -1; | ||
141 | } | ||
142 | if (BN_cmp(g_x, grp_p) >= 0) { | ||
143 | error("%s: g_x > g", __func__); | ||
144 | return -1; | ||
145 | } | ||
146 | |||
147 | h = g_v = r = tmp = v = NULL; | ||
148 | if ((bn_ctx = BN_CTX_new()) == NULL) { | ||
149 | error("%s: BN_CTX_new", __func__); | ||
150 | goto out; | ||
151 | } | ||
152 | if ((g_v = BN_new()) == NULL || | ||
153 | (r = BN_new()) == NULL || | ||
154 | (tmp = BN_new()) == NULL) { | ||
155 | error("%s: BN_new", __func__); | ||
156 | goto out; | ||
157 | } | ||
158 | |||
159 | /* | ||
160 | * v must be a random element of Zq, so 1 <= v < q | ||
161 | * we also exclude v = 1, since g^1 looks dangerous | ||
162 | */ | ||
163 | if ((v = bn_rand_range_gt_one(grp_p)) == NULL) { | ||
164 | error("%s: bn_rand_range2", __func__); | ||
165 | goto out; | ||
166 | } | ||
167 | SCHNORR_DEBUG_BN((v, "%s: v = ", __func__)); | ||
168 | |||
169 | /* g_v = g^v mod p */ | ||
170 | if (BN_mod_exp(g_v, grp_g, v, grp_p, bn_ctx) == -1) { | ||
171 | error("%s: BN_mod_exp (g^v mod p)", __func__); | ||
172 | goto out; | ||
173 | } | ||
174 | SCHNORR_DEBUG_BN((g_v, "%s: g_v = ", __func__)); | ||
175 | |||
176 | /* h = H(g || g^v || g^x || id) */ | ||
177 | if ((h = schnorr_hash(grp_p, grp_q, grp_g, hash_alg, g_v, g_x, | ||
178 | id, idlen)) == NULL) { | ||
179 | error("%s: schnorr_hash failed", __func__); | ||
180 | goto out; | ||
181 | } | ||
182 | |||
183 | /* r = v - xh mod q */ | ||
184 | if (BN_mod_mul(tmp, x, h, grp_q, bn_ctx) == -1) { | ||
185 | error("%s: BN_mod_mul (tmp = xv mod q)", __func__); | ||
186 | goto out; | ||
187 | } | ||
188 | if (BN_mod_sub(r, v, tmp, grp_q, bn_ctx) == -1) { | ||
189 | error("%s: BN_mod_mul (r = v - tmp)", __func__); | ||
190 | goto out; | ||
191 | } | ||
192 | SCHNORR_DEBUG_BN((g_v, "%s: e = ", __func__)); | ||
193 | SCHNORR_DEBUG_BN((r, "%s: r = ", __func__)); | ||
194 | |||
195 | *e_p = g_v; | ||
196 | *r_p = r; | ||
197 | |||
198 | success = 0; | ||
199 | out: | ||
200 | BN_CTX_free(bn_ctx); | ||
201 | if (h != NULL) | ||
202 | BN_clear_free(h); | ||
203 | if (v != NULL) | ||
204 | BN_clear_free(v); | ||
205 | BN_clear_free(tmp); | ||
206 | |||
207 | return success; | ||
208 | } | ||
209 | |||
210 | /* | ||
211 | * Generate Schnorr signature to prove knowledge of private value 'x' used | ||
212 | * in public exponent g^x, under group defined by 'grp_p', 'grp_q' and 'grp_g' | ||
213 | * using a SHA256 hash. | ||
214 | * 'idlen' bytes from 'id' will be included in the signature hash as an anti- | ||
215 | * replay salt. | ||
216 | * On success, 0 is returned and *siglen bytes of signature are returned in | ||
217 | * *sig (caller to free). Returns -1 on failure. | ||
218 | */ | ||
219 | int | ||
220 | schnorr_sign_buf(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g, | ||
221 | const BIGNUM *x, const BIGNUM *g_x, const u_char *id, u_int idlen, | ||
222 | u_char **sig, u_int *siglen) | ||
223 | { | ||
224 | Buffer b; | ||
225 | BIGNUM *r, *e; | ||
226 | |||
227 | if (schnorr_sign(grp_p, grp_q, grp_g, SSH_DIGEST_SHA256, | ||
228 | x, g_x, id, idlen, &r, &e) != 0) | ||
229 | return -1; | ||
230 | |||
231 | /* Signature is (e, r) */ | ||
232 | buffer_init(&b); | ||
233 | /* XXX sigtype-hash as string? */ | ||
234 | buffer_put_bignum2(&b, e); | ||
235 | buffer_put_bignum2(&b, r); | ||
236 | *siglen = buffer_len(&b); | ||
237 | *sig = xmalloc(*siglen); | ||
238 | memcpy(*sig, buffer_ptr(&b), *siglen); | ||
239 | SCHNORR_DEBUG_BUF((buffer_ptr(&b), buffer_len(&b), | ||
240 | "%s: sigblob", __func__)); | ||
241 | buffer_free(&b); | ||
242 | |||
243 | BN_clear_free(r); | ||
244 | BN_clear_free(e); | ||
245 | |||
246 | return 0; | ||
247 | } | ||
248 | |||
249 | /* | ||
250 | * Verify Schnorr signature { r (v - xh mod q), e (g^v mod p) } against | ||
251 | * public exponent g_x (g^x) under group defined by 'grp_p', 'grp_q' and | ||
252 | * 'grp_g' using hash "hash_alg". | ||
253 | * Signature hash will be salted with 'idlen' bytes from 'id'. | ||
254 | * Returns -1 on failure, 0 on incorrect signature or 1 on matching signature. | ||
255 | */ | ||
256 | int | ||
257 | schnorr_verify(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g, | ||
258 | int hash_alg, const BIGNUM *g_x, const u_char *id, u_int idlen, | ||
259 | const BIGNUM *r, const BIGNUM *e) | ||
260 | { | ||
261 | int success = -1; | ||
262 | BIGNUM *h = NULL, *g_xh = NULL, *g_r = NULL, *gx_q = NULL; | ||
263 | BIGNUM *expected = NULL; | ||
264 | BN_CTX *bn_ctx; | ||
265 | |||
266 | SCHNORR_DEBUG_BN((g_x, "%s: g_x = ", __func__)); | ||
267 | |||
268 | /* Avoid degenerate cases: g^0 yields a spoofable signature */ | ||
269 | if (BN_cmp(g_x, BN_value_one()) <= 0) { | ||
270 | error("%s: g_x <= 1", __func__); | ||
271 | return -1; | ||
272 | } | ||
273 | if (BN_cmp(g_x, grp_p) >= 0) { | ||
274 | error("%s: g_x >= p", __func__); | ||
275 | return -1; | ||
276 | } | ||
277 | |||
278 | h = g_xh = g_r = expected = NULL; | ||
279 | if ((bn_ctx = BN_CTX_new()) == NULL) { | ||
280 | error("%s: BN_CTX_new", __func__); | ||
281 | goto out; | ||
282 | } | ||
283 | if ((g_xh = BN_new()) == NULL || | ||
284 | (g_r = BN_new()) == NULL || | ||
285 | (gx_q = BN_new()) == NULL || | ||
286 | (expected = BN_new()) == NULL) { | ||
287 | error("%s: BN_new", __func__); | ||
288 | goto out; | ||
289 | } | ||
290 | |||
291 | SCHNORR_DEBUG_BN((e, "%s: e = ", __func__)); | ||
292 | SCHNORR_DEBUG_BN((r, "%s: r = ", __func__)); | ||
293 | |||
294 | /* gx_q = (g^x)^q must === 1 mod p */ | ||
295 | if (BN_mod_exp(gx_q, g_x, grp_q, grp_p, bn_ctx) == -1) { | ||
296 | error("%s: BN_mod_exp (g_x^q mod p)", __func__); | ||
297 | goto out; | ||
298 | } | ||
299 | if (BN_cmp(gx_q, BN_value_one()) != 0) { | ||
300 | error("%s: Invalid signature (g^x)^q != 1 mod p", __func__); | ||
301 | goto out; | ||
302 | } | ||
303 | |||
304 | SCHNORR_DEBUG_BN((g_xh, "%s: g_xh = ", __func__)); | ||
305 | /* h = H(g || g^v || g^x || id) */ | ||
306 | if ((h = schnorr_hash(grp_p, grp_q, grp_g, hash_alg, e, g_x, | ||
307 | id, idlen)) == NULL) { | ||
308 | error("%s: schnorr_hash failed", __func__); | ||
309 | goto out; | ||
310 | } | ||
311 | |||
312 | /* g_xh = (g^x)^h */ | ||
313 | if (BN_mod_exp(g_xh, g_x, h, grp_p, bn_ctx) == -1) { | ||
314 | error("%s: BN_mod_exp (g_x^h mod p)", __func__); | ||
315 | goto out; | ||
316 | } | ||
317 | SCHNORR_DEBUG_BN((g_xh, "%s: g_xh = ", __func__)); | ||
318 | |||
319 | /* g_r = g^r */ | ||
320 | if (BN_mod_exp(g_r, grp_g, r, grp_p, bn_ctx) == -1) { | ||
321 | error("%s: BN_mod_exp (g_x^h mod p)", __func__); | ||
322 | goto out; | ||
323 | } | ||
324 | SCHNORR_DEBUG_BN((g_r, "%s: g_r = ", __func__)); | ||
325 | |||
326 | /* expected = g^r * g_xh */ | ||
327 | if (BN_mod_mul(expected, g_r, g_xh, grp_p, bn_ctx) == -1) { | ||
328 | error("%s: BN_mod_mul (expected = g_r mod p)", __func__); | ||
329 | goto out; | ||
330 | } | ||
331 | SCHNORR_DEBUG_BN((expected, "%s: expected = ", __func__)); | ||
332 | |||
333 | /* Check e == expected */ | ||
334 | success = BN_cmp(expected, e) == 0; | ||
335 | out: | ||
336 | BN_CTX_free(bn_ctx); | ||
337 | if (h != NULL) | ||
338 | BN_clear_free(h); | ||
339 | if (gx_q != NULL) | ||
340 | BN_clear_free(gx_q); | ||
341 | if (g_xh != NULL) | ||
342 | BN_clear_free(g_xh); | ||
343 | if (g_r != NULL) | ||
344 | BN_clear_free(g_r); | ||
345 | if (expected != NULL) | ||
346 | BN_clear_free(expected); | ||
347 | return success; | ||
348 | } | ||
349 | |||
350 | /* | ||
351 | * Verify Schnorr signature 'sig' of length 'siglen' against public exponent | ||
352 | * g_x (g^x) under group defined by 'grp_p', 'grp_q' and 'grp_g' using a | ||
353 | * SHA256 hash. | ||
354 | * Signature hash will be salted with 'idlen' bytes from 'id'. | ||
355 | * Returns -1 on failure, 0 on incorrect signature or 1 on matching signature. | ||
356 | */ | ||
357 | int | ||
358 | schnorr_verify_buf(const BIGNUM *grp_p, const BIGNUM *grp_q, | ||
359 | const BIGNUM *grp_g, | ||
360 | const BIGNUM *g_x, const u_char *id, u_int idlen, | ||
361 | const u_char *sig, u_int siglen) | ||
362 | { | ||
363 | Buffer b; | ||
364 | int ret = -1; | ||
365 | u_int rlen; | ||
366 | BIGNUM *r, *e; | ||
367 | |||
368 | e = r = NULL; | ||
369 | if ((e = BN_new()) == NULL || | ||
370 | (r = BN_new()) == NULL) { | ||
371 | error("%s: BN_new", __func__); | ||
372 | goto out; | ||
373 | } | ||
374 | |||
375 | /* Extract g^v and r from signature blob */ | ||
376 | buffer_init(&b); | ||
377 | buffer_append(&b, sig, siglen); | ||
378 | SCHNORR_DEBUG_BUF((buffer_ptr(&b), buffer_len(&b), | ||
379 | "%s: sigblob", __func__)); | ||
380 | buffer_get_bignum2(&b, e); | ||
381 | buffer_get_bignum2(&b, r); | ||
382 | rlen = buffer_len(&b); | ||
383 | buffer_free(&b); | ||
384 | if (rlen != 0) { | ||
385 | error("%s: remaining bytes in signature %d", __func__, rlen); | ||
386 | goto out; | ||
387 | } | ||
388 | |||
389 | ret = schnorr_verify(grp_p, grp_q, grp_g, SSH_DIGEST_SHA256, | ||
390 | g_x, id, idlen, r, e); | ||
391 | out: | ||
392 | BN_clear_free(e); | ||
393 | BN_clear_free(r); | ||
394 | |||
395 | return ret; | ||
396 | } | ||
397 | |||
398 | /* Helper functions */ | ||
399 | |||
400 | /* | ||
401 | * Generate uniformly distributed random number in range (1, high). | ||
402 | * Return number on success, NULL on failure. | ||
403 | */ | ||
404 | BIGNUM * | ||
405 | bn_rand_range_gt_one(const BIGNUM *high) | ||
406 | { | ||
407 | BIGNUM *r, *tmp; | ||
408 | int success = -1; | ||
409 | |||
410 | if ((tmp = BN_new()) == NULL) { | ||
411 | error("%s: BN_new", __func__); | ||
412 | return NULL; | ||
413 | } | ||
414 | if ((r = BN_new()) == NULL) { | ||
415 | error("%s: BN_new failed", __func__); | ||
416 | goto out; | ||
417 | } | ||
418 | if (BN_set_word(tmp, 2) != 1) { | ||
419 | error("%s: BN_set_word(tmp, 2)", __func__); | ||
420 | goto out; | ||
421 | } | ||
422 | if (BN_sub(tmp, high, tmp) == -1) { | ||
423 | error("%s: BN_sub failed (tmp = high - 2)", __func__); | ||
424 | goto out; | ||
425 | } | ||
426 | if (BN_rand_range(r, tmp) == -1) { | ||
427 | error("%s: BN_rand_range failed", __func__); | ||
428 | goto out; | ||
429 | } | ||
430 | if (BN_set_word(tmp, 2) != 1) { | ||
431 | error("%s: BN_set_word(tmp, 2)", __func__); | ||
432 | goto out; | ||
433 | } | ||
434 | if (BN_add(r, r, tmp) == -1) { | ||
435 | error("%s: BN_add failed (r = r + 2)", __func__); | ||
436 | goto out; | ||
437 | } | ||
438 | success = 0; | ||
439 | out: | ||
440 | BN_clear_free(tmp); | ||
441 | if (success == 0) | ||
442 | return r; | ||
443 | BN_clear_free(r); | ||
444 | return NULL; | ||
445 | } | ||
446 | |||
447 | /* XXX convert all callers of this to use ssh_digest_memory() directly */ | ||
448 | /* | ||
449 | * Hash contents of buffer 'b' with hash 'md'. Returns 0 on success, | ||
450 | * with digest via 'digestp' (caller to free) and length via 'lenp'. | ||
451 | * Returns -1 on failure. | ||
452 | */ | ||
453 | int | ||
454 | hash_buffer(const u_char *buf, u_int len, int hash_alg, | ||
455 | u_char **digestp, u_int *lenp) | ||
456 | { | ||
457 | u_char digest[SSH_DIGEST_MAX_LENGTH]; | ||
458 | u_int digest_len = ssh_digest_bytes(hash_alg); | ||
459 | |||
460 | if (digest_len == 0) { | ||
461 | error("%s: invalid hash", __func__); | ||
462 | return -1; | ||
463 | } | ||
464 | if (ssh_digest_memory(hash_alg, buf, len, digest, digest_len) != 0) { | ||
465 | error("%s: digest_memory failed", __func__); | ||
466 | return -1; | ||
467 | } | ||
468 | *digestp = xmalloc(digest_len); | ||
469 | *lenp = digest_len; | ||
470 | memcpy(*digestp, digest, *lenp); | ||
471 | bzero(digest, sizeof(digest)); | ||
472 | digest_len = 0; | ||
473 | return 0; | ||
474 | } | ||
475 | |||
476 | /* print formatted string followed by bignum */ | ||
477 | void | ||
478 | debug3_bn(const BIGNUM *n, const char *fmt, ...) | ||
479 | { | ||
480 | char *out, *h; | ||
481 | va_list args; | ||
482 | int ret; | ||
483 | |||
484 | out = NULL; | ||
485 | va_start(args, fmt); | ||
486 | ret = vasprintf(&out, fmt, args); | ||
487 | va_end(args); | ||
488 | if (ret == -1 || out == NULL) | ||
489 | fatal("%s: vasprintf failed", __func__); | ||
490 | |||
491 | if (n == NULL) | ||
492 | debug3("%s(null)", out); | ||
493 | else { | ||
494 | h = BN_bn2hex(n); | ||
495 | debug3("%s0x%s", out, h); | ||
496 | free(h); | ||
497 | } | ||
498 | free(out); | ||
499 | } | ||
500 | |||
501 | /* print formatted string followed by buffer contents in hex */ | ||
502 | void | ||
503 | debug3_buf(const u_char *buf, u_int len, const char *fmt, ...) | ||
504 | { | ||
505 | char *out, h[65]; | ||
506 | u_int i, j; | ||
507 | va_list args; | ||
508 | int ret; | ||
509 | |||
510 | out = NULL; | ||
511 | va_start(args, fmt); | ||
512 | ret = vasprintf(&out, fmt, args); | ||
513 | va_end(args); | ||
514 | if (ret == -1 || out == NULL) | ||
515 | fatal("%s: vasprintf failed", __func__); | ||
516 | |||
517 | debug3("%s length %u%s", out, len, buf == NULL ? " (null)" : ""); | ||
518 | free(out); | ||
519 | if (buf == NULL) | ||
520 | return; | ||
521 | |||
522 | *h = '\0'; | ||
523 | for (i = j = 0; i < len; i++) { | ||
524 | snprintf(h + j, sizeof(h) - j, "%02x", buf[i]); | ||
525 | j += 2; | ||
526 | if (j >= sizeof(h) - 1 || i == len - 1) { | ||
527 | debug3(" %s", h); | ||
528 | *h = '\0'; | ||
529 | j = 0; | ||
530 | } | ||
531 | } | ||
532 | } | ||
533 | |||
534 | /* | ||
535 | * Construct a MODP group from hex strings p (which must be a safe | ||
536 | * prime) and g, automatically calculating subgroup q as (p / 2) | ||
537 | */ | ||
538 | struct modp_group * | ||
539 | modp_group_from_g_and_safe_p(const char *grp_g, const char *grp_p) | ||
540 | { | ||
541 | struct modp_group *ret; | ||
542 | |||
543 | ret = xcalloc(1, sizeof(*ret)); | ||
544 | ret->p = ret->q = ret->g = NULL; | ||
545 | if (BN_hex2bn(&ret->p, grp_p) == 0 || | ||
546 | BN_hex2bn(&ret->g, grp_g) == 0) | ||
547 | fatal("%s: BN_hex2bn", __func__); | ||
548 | /* Subgroup order is p/2 (p is a safe prime) */ | ||
549 | if ((ret->q = BN_new()) == NULL) | ||
550 | fatal("%s: BN_new", __func__); | ||
551 | if (BN_rshift1(ret->q, ret->p) != 1) | ||
552 | fatal("%s: BN_rshift1", __func__); | ||
553 | |||
554 | return ret; | ||
555 | } | ||
556 | |||
557 | void | ||
558 | modp_group_free(struct modp_group *grp) | ||
559 | { | ||
560 | if (grp->g != NULL) | ||
561 | BN_clear_free(grp->g); | ||
562 | if (grp->p != NULL) | ||
563 | BN_clear_free(grp->p); | ||
564 | if (grp->q != NULL) | ||
565 | BN_clear_free(grp->q); | ||
566 | bzero(grp, sizeof(*grp)); | ||
567 | free(grp); | ||
568 | } | ||
569 | |||
570 | /* main() function for self-test */ | ||
571 | |||
572 | #ifdef SCHNORR_MAIN | ||
573 | static void | ||
574 | schnorr_selftest_one(const BIGNUM *grp_p, const BIGNUM *grp_q, | ||
575 | const BIGNUM *grp_g, const BIGNUM *x) | ||
576 | { | ||
577 | BIGNUM *g_x; | ||
578 | u_char *sig; | ||
579 | u_int siglen; | ||
580 | BN_CTX *bn_ctx; | ||
581 | |||
582 | if ((bn_ctx = BN_CTX_new()) == NULL) | ||
583 | fatal("%s: BN_CTX_new", __func__); | ||
584 | if ((g_x = BN_new()) == NULL) | ||
585 | fatal("%s: BN_new", __func__); | ||
586 | |||
587 | if (BN_mod_exp(g_x, grp_g, x, grp_p, bn_ctx) == -1) | ||
588 | fatal("%s: g_x", __func__); | ||
589 | if (schnorr_sign_buf(grp_p, grp_q, grp_g, x, g_x, "junk", 4, | ||
590 | &sig, &siglen)) | ||
591 | fatal("%s: schnorr_sign", __func__); | ||
592 | if (schnorr_verify_buf(grp_p, grp_q, grp_g, g_x, "junk", 4, | ||
593 | sig, siglen) != 1) | ||
594 | fatal("%s: verify fail", __func__); | ||
595 | if (schnorr_verify_buf(grp_p, grp_q, grp_g, g_x, "JUNK", 4, | ||
596 | sig, siglen) != 0) | ||
597 | fatal("%s: verify should have failed (bad ID)", __func__); | ||
598 | sig[4] ^= 1; | ||
599 | if (schnorr_verify_buf(grp_p, grp_q, grp_g, g_x, "junk", 4, | ||
600 | sig, siglen) != 0) | ||
601 | fatal("%s: verify should have failed (bit error)", __func__); | ||
602 | free(sig); | ||
603 | BN_free(g_x); | ||
604 | BN_CTX_free(bn_ctx); | ||
605 | } | ||
606 | |||
607 | static void | ||
608 | schnorr_selftest(void) | ||
609 | { | ||
610 | BIGNUM *x; | ||
611 | struct modp_group *grp; | ||
612 | u_int i; | ||
613 | char *hh; | ||
614 | |||
615 | grp = jpake_default_group(); | ||
616 | if ((x = BN_new()) == NULL) | ||
617 | fatal("%s: BN_new", __func__); | ||
618 | SCHNORR_DEBUG_BN((grp->p, "%s: grp->p = ", __func__)); | ||
619 | SCHNORR_DEBUG_BN((grp->q, "%s: grp->q = ", __func__)); | ||
620 | SCHNORR_DEBUG_BN((grp->g, "%s: grp->g = ", __func__)); | ||
621 | |||
622 | /* [1, 20) */ | ||
623 | for (i = 1; i < 20; i++) { | ||
624 | printf("x = %u\n", i); | ||
625 | fflush(stdout); | ||
626 | if (BN_set_word(x, i) != 1) | ||
627 | fatal("%s: set x word", __func__); | ||
628 | schnorr_selftest_one(grp->p, grp->q, grp->g, x); | ||
629 | } | ||
630 | |||
631 | /* 100 x random [0, p) */ | ||
632 | for (i = 0; i < 100; i++) { | ||
633 | if (BN_rand_range(x, grp->p) != 1) | ||
634 | fatal("%s: BN_rand_range", __func__); | ||
635 | hh = BN_bn2hex(x); | ||
636 | printf("x = (random) 0x%s\n", hh); | ||
637 | free(hh); | ||
638 | fflush(stdout); | ||
639 | schnorr_selftest_one(grp->p, grp->q, grp->g, x); | ||
640 | } | ||
641 | |||
642 | /* [q-20, q) */ | ||
643 | if (BN_set_word(x, 20) != 1) | ||
644 | fatal("%s: BN_set_word (x = 20)", __func__); | ||
645 | if (BN_sub(x, grp->q, x) != 1) | ||
646 | fatal("%s: BN_sub (q - x)", __func__); | ||
647 | for (i = 0; i < 19; i++) { | ||
648 | hh = BN_bn2hex(x); | ||
649 | printf("x = (q - %d) 0x%s\n", 20 - i, hh); | ||
650 | free(hh); | ||
651 | fflush(stdout); | ||
652 | schnorr_selftest_one(grp->p, grp->q, grp->g, x); | ||
653 | if (BN_add(x, x, BN_value_one()) != 1) | ||
654 | fatal("%s: BN_add (x + 1)", __func__); | ||
655 | } | ||
656 | BN_free(x); | ||
657 | } | ||
658 | |||
659 | int | ||
660 | main(int argc, char **argv) | ||
661 | { | ||
662 | log_init(argv[0], SYSLOG_LEVEL_DEBUG3, SYSLOG_FACILITY_USER, 1); | ||
663 | |||
664 | schnorr_selftest(); | ||
665 | return 0; | ||
666 | } | ||
667 | #endif | ||
668 | |||
diff --git a/schnorr.h b/schnorr.h deleted file mode 100644 index e2405c102..000000000 --- a/schnorr.h +++ /dev/null | |||
@@ -1,60 +0,0 @@ | |||
1 | /* $OpenBSD: schnorr.h,v 1.2 2014/01/09 23:20:00 djm Exp $ */ | ||
2 | /* | ||
3 | * Copyright (c) 2009 Damien Miller. All rights reserved. | ||
4 | * | ||
5 | * Permission to use, copy, modify, and distribute this software for any | ||
6 | * purpose with or without fee is hereby granted, provided that the above | ||
7 | * copyright notice and this permission notice appear in all copies. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
10 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
11 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
12 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
13 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
16 | */ | ||
17 | |||
18 | #ifndef SCHNORR_H | ||
19 | #define SCHNORR_H | ||
20 | |||
21 | #include <sys/types.h> | ||
22 | |||
23 | #include <openssl/bn.h> | ||
24 | |||
25 | struct modp_group { | ||
26 | BIGNUM *p, *q, *g; | ||
27 | }; | ||
28 | |||
29 | BIGNUM *bn_rand_range_gt_one(const BIGNUM *high); | ||
30 | int hash_buffer(const u_char *, u_int, int, u_char **, u_int *); | ||
31 | void debug3_bn(const BIGNUM *, const char *, ...) | ||
32 | __attribute__((__nonnull__ (2))) | ||
33 | __attribute__((format(printf, 2, 3))); | ||
34 | void debug3_buf(const u_char *, u_int, const char *, ...) | ||
35 | __attribute__((__nonnull__ (3))) | ||
36 | __attribute__((format(printf, 3, 4))); | ||
37 | struct modp_group *modp_group_from_g_and_safe_p(const char *, const char *); | ||
38 | void modp_group_free(struct modp_group *); | ||
39 | |||
40 | /* Signature and verification functions */ | ||
41 | int | ||
42 | schnorr_sign(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g, | ||
43 | int hash_alg, const BIGNUM *x, const BIGNUM *g_x, | ||
44 | const u_char *id, u_int idlen, BIGNUM **r_p, BIGNUM **e_p); | ||
45 | int | ||
46 | schnorr_sign_buf(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g, | ||
47 | const BIGNUM *x, const BIGNUM *g_x, const u_char *id, u_int idlen, | ||
48 | u_char **sig, u_int *siglen); | ||
49 | int | ||
50 | schnorr_verify(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g, | ||
51 | int hash_alg, const BIGNUM *g_x, const u_char *id, u_int idlen, | ||
52 | const BIGNUM *r, const BIGNUM *e); | ||
53 | int | ||
54 | schnorr_verify_buf(const BIGNUM *grp_p, const BIGNUM *grp_q, | ||
55 | const BIGNUM *grp_g, | ||
56 | const BIGNUM *g_x, const u_char *id, u_int idlen, | ||
57 | const u_char *sig, u_int siglen); | ||
58 | |||
59 | #endif /* JPAKE_H */ | ||
60 | |||
@@ -160,4 +160,4 @@ AUTHORS | |||
160 | Timo Rinne <tri@iki.fi> | 160 | Timo Rinne <tri@iki.fi> |
161 | Tatu Ylonen <ylo@cs.hut.fi> | 161 | Tatu Ylonen <ylo@cs.hut.fi> |
162 | 162 | ||
163 | OpenBSD 5.4 October 20, 2013 OpenBSD 5.4 | 163 | OpenBSD 5.5 October 20, 2013 OpenBSD 5.5 |
diff --git a/servconf.c b/servconf.c index 9bcd05bf2..7ba65d51d 100644 --- a/servconf.c +++ b/servconf.c | |||
@@ -1,5 +1,5 @@ | |||
1 | 1 | ||
2 | /* $OpenBSD: servconf.c,v 1.248 2013/12/06 13:39:49 markus Exp $ */ | 2 | /* $OpenBSD: servconf.c,v 1.249 2014/01/29 06:18:35 djm Exp $ */ |
3 | /* | 3 | /* |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
5 | * All rights reserved | 5 | * All rights reserved |
@@ -147,7 +147,6 @@ initialize_server_options(ServerOptions *options) | |||
147 | options->chroot_directory = NULL; | 147 | options->chroot_directory = NULL; |
148 | options->authorized_keys_command = NULL; | 148 | options->authorized_keys_command = NULL; |
149 | options->authorized_keys_command_user = NULL; | 149 | options->authorized_keys_command_user = NULL; |
150 | options->zero_knowledge_password_authentication = -1; | ||
151 | options->revoked_keys_file = NULL; | 150 | options->revoked_keys_file = NULL; |
152 | options->trusted_user_ca_keys = NULL; | 151 | options->trusted_user_ca_keys = NULL; |
153 | options->authorized_principals_file = NULL; | 152 | options->authorized_principals_file = NULL; |
@@ -295,8 +294,6 @@ fill_default_server_options(ServerOptions *options) | |||
295 | } | 294 | } |
296 | if (options->permit_tun == -1) | 295 | if (options->permit_tun == -1) |
297 | options->permit_tun = SSH_TUNMODE_NO; | 296 | options->permit_tun = SSH_TUNMODE_NO; |
298 | if (options->zero_knowledge_password_authentication == -1) | ||
299 | options->zero_knowledge_password_authentication = 0; | ||
300 | if (options->ip_qos_interactive == -1) | 297 | if (options->ip_qos_interactive == -1) |
301 | options->ip_qos_interactive = IPTOS_LOWDELAY; | 298 | options->ip_qos_interactive = IPTOS_LOWDELAY; |
302 | if (options->ip_qos_bulk == -1) | 299 | if (options->ip_qos_bulk == -1) |
@@ -346,7 +343,7 @@ typedef enum { | |||
346 | sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel, | 343 | sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel, |
347 | sMatch, sPermitOpen, sForceCommand, sChrootDirectory, | 344 | sMatch, sPermitOpen, sForceCommand, sChrootDirectory, |
348 | sUsePrivilegeSeparation, sAllowAgentForwarding, | 345 | sUsePrivilegeSeparation, sAllowAgentForwarding, |
349 | sZeroKnowledgePasswordAuthentication, sHostCertificate, | 346 | sHostCertificate, |
350 | sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile, | 347 | sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile, |
351 | sKexAlgorithms, sIPQoS, sVersionAddendum, | 348 | sKexAlgorithms, sIPQoS, sVersionAddendum, |
352 | sAuthorizedKeysCommand, sAuthorizedKeysCommandUser, | 349 | sAuthorizedKeysCommand, sAuthorizedKeysCommandUser, |
@@ -418,11 +415,6 @@ static struct { | |||
418 | { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, | 415 | { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, |
419 | { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, | 416 | { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, |
420 | { "skeyauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, /* alias */ | 417 | { "skeyauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, /* alias */ |
421 | #ifdef JPAKE | ||
422 | { "zeroknowledgepasswordauthentication", sZeroKnowledgePasswordAuthentication, SSHCFG_ALL }, | ||
423 | #else | ||
424 | { "zeroknowledgepasswordauthentication", sUnsupported, SSHCFG_ALL }, | ||
425 | #endif | ||
426 | { "checkmail", sDeprecated, SSHCFG_GLOBAL }, | 418 | { "checkmail", sDeprecated, SSHCFG_GLOBAL }, |
427 | { "listenaddress", sListenAddress, SSHCFG_GLOBAL }, | 419 | { "listenaddress", sListenAddress, SSHCFG_GLOBAL }, |
428 | { "addressfamily", sAddressFamily, SSHCFG_GLOBAL }, | 420 | { "addressfamily", sAddressFamily, SSHCFG_GLOBAL }, |
@@ -1102,10 +1094,6 @@ process_server_config_line(ServerOptions *options, char *line, | |||
1102 | intptr = &options->password_authentication; | 1094 | intptr = &options->password_authentication; |
1103 | goto parse_flag; | 1095 | goto parse_flag; |
1104 | 1096 | ||
1105 | case sZeroKnowledgePasswordAuthentication: | ||
1106 | intptr = &options->zero_knowledge_password_authentication; | ||
1107 | goto parse_flag; | ||
1108 | |||
1109 | case sKbdInteractiveAuthentication: | 1097 | case sKbdInteractiveAuthentication: |
1110 | intptr = &options->kbd_interactive_authentication; | 1098 | intptr = &options->kbd_interactive_authentication; |
1111 | goto parse_flag; | 1099 | goto parse_flag; |
@@ -1767,7 +1755,6 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) | |||
1767 | M_CP_INTOPT(hostbased_authentication); | 1755 | M_CP_INTOPT(hostbased_authentication); |
1768 | M_CP_INTOPT(hostbased_uses_name_from_packet_only); | 1756 | M_CP_INTOPT(hostbased_uses_name_from_packet_only); |
1769 | M_CP_INTOPT(kbd_interactive_authentication); | 1757 | M_CP_INTOPT(kbd_interactive_authentication); |
1770 | M_CP_INTOPT(zero_knowledge_password_authentication); | ||
1771 | M_CP_INTOPT(permit_root_login); | 1758 | M_CP_INTOPT(permit_root_login); |
1772 | M_CP_INTOPT(permit_empty_passwd); | 1759 | M_CP_INTOPT(permit_empty_passwd); |
1773 | 1760 | ||
@@ -2010,10 +1997,6 @@ dump_config(ServerOptions *o) | |||
2010 | dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); | 1997 | dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); |
2011 | dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds); | 1998 | dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds); |
2012 | #endif | 1999 | #endif |
2013 | #ifdef JPAKE | ||
2014 | dump_cfg_fmtint(sZeroKnowledgePasswordAuthentication, | ||
2015 | o->zero_knowledge_password_authentication); | ||
2016 | #endif | ||
2017 | dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication); | 2000 | dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication); |
2018 | dump_cfg_fmtint(sKbdInteractiveAuthentication, | 2001 | dump_cfg_fmtint(sKbdInteractiveAuthentication, |
2019 | o->kbd_interactive_authentication); | 2002 | o->kbd_interactive_authentication); |
diff --git a/servconf.h b/servconf.h index 8812c5aab..752d1c5ae 100644 --- a/servconf.h +++ b/servconf.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: servconf.h,v 1.111 2013/12/05 01:16:41 djm Exp $ */ | 1 | /* $OpenBSD: servconf.h,v 1.112 2014/01/29 06:18:35 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
@@ -117,8 +117,6 @@ typedef struct { | |||
117 | * authentication. */ | 117 | * authentication. */ |
118 | int kbd_interactive_authentication; /* If true, permit */ | 118 | int kbd_interactive_authentication; /* If true, permit */ |
119 | int challenge_response_authentication; | 119 | int challenge_response_authentication; |
120 | int zero_knowledge_password_authentication; | ||
121 | /* If true, permit jpake auth */ | ||
122 | int permit_empty_passwd; /* If false, do not permit empty | 120 | int permit_empty_passwd; /* If false, do not permit empty |
123 | * passwords. */ | 121 | * passwords. */ |
124 | int permit_user_env; /* If true, read ~/.ssh/environment */ | 122 | int permit_user_env; /* If true, read ~/.ssh/environment */ |
diff --git a/serverloop.c b/serverloop.c index 5b2f8028d..2f8e3a06a 100644 --- a/serverloop.c +++ b/serverloop.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: serverloop.c,v 1.169 2013/12/19 00:19:12 dtucker Exp $ */ | 1 | /* $OpenBSD: serverloop.c,v 1.170 2014/02/02 03:44:31 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * 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) | |||
920 | data = packet_get_string(&data_len); | 920 | data = packet_get_string(&data_len); |
921 | packet_check_eom(); | 921 | packet_check_eom(); |
922 | buffer_append(&stdin_buffer, data, data_len); | 922 | buffer_append(&stdin_buffer, data, data_len); |
923 | memset(data, 0, data_len); | 923 | explicit_bzero(data, data_len); |
924 | free(data); | 924 | free(data); |
925 | } | 925 | } |
926 | 926 | ||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: session.c,v 1.269 2014/01/18 09:36:26 dtucker Exp $ */ | 1 | /* $OpenBSD: session.c,v 1.270 2014/01/31 16:39:19 tedu Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 3 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
4 | * All rights reserved | 4 | * All rights reserved |
@@ -978,6 +978,11 @@ child_set_env(char ***envp, u_int *envsizep, const char *name, | |||
978 | u_int envsize; | 978 | u_int envsize; |
979 | u_int i, namelen; | 979 | u_int i, namelen; |
980 | 980 | ||
981 | if (strchr(name, '=') != NULL) { | ||
982 | error("Invalid environment variable \"%.100s\"", name); | ||
983 | return; | ||
984 | } | ||
985 | |||
981 | /* | 986 | /* |
982 | * If we're passed an uninitialized list, allocate a single null | 987 | * If we're passed an uninitialized list, allocate a single null |
983 | * entry before continuing. | 988 | * entry before continuing. |
@@ -1889,7 +1894,7 @@ session_unused(int id) | |||
1889 | fatal("%s: insane session id %d (max %d nalloc %d)", | 1894 | fatal("%s: insane session id %d (max %d nalloc %d)", |
1890 | __func__, id, options.max_sessions, sessions_nalloc); | 1895 | __func__, id, options.max_sessions, sessions_nalloc); |
1891 | } | 1896 | } |
1892 | bzero(&sessions[id], sizeof(*sessions)); | 1897 | memset(&sessions[id], 0, sizeof(*sessions)); |
1893 | sessions[id].self = id; | 1898 | sessions[id].self = id; |
1894 | sessions[id].used = 0; | 1899 | sessions[id].used = 0; |
1895 | sessions[id].chanid = -1; | 1900 | sessions[id].chanid = -1; |
@@ -2225,8 +2230,8 @@ session_env_req(Session *s) | |||
2225 | char *name, *val; | 2230 | char *name, *val; |
2226 | u_int name_len, val_len, i; | 2231 | u_int name_len, val_len, i; |
2227 | 2232 | ||
2228 | name = packet_get_string(&name_len); | 2233 | name = packet_get_cstring(&name_len); |
2229 | val = packet_get_string(&val_len); | 2234 | val = packet_get_cstring(&val_len); |
2230 | packet_check_eom(); | 2235 | packet_check_eom(); |
2231 | 2236 | ||
2232 | /* Don't set too many environment variables */ | 2237 | /* Don't set too many environment variables */ |
diff --git a/sftp-client.c b/sftp-client.c index fc035f2ef..2f5907c85 100644 --- a/sftp-client.c +++ b/sftp-client.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sftp-client.c,v 1.113 2014/01/17 00:21:06 djm Exp $ */ | 1 | /* $OpenBSD: sftp-client.c,v 1.114 2014/01/31 16:39:19 tedu Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org> | 3 | * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org> |
4 | * | 4 | * |
@@ -310,7 +310,7 @@ get_decode_statvfs(struct sftp_conn *conn, struct sftp_statvfs *st, | |||
310 | SSH2_FXP_EXTENDED_REPLY, type); | 310 | SSH2_FXP_EXTENDED_REPLY, type); |
311 | } | 311 | } |
312 | 312 | ||
313 | bzero(st, sizeof(*st)); | 313 | memset(st, 0, sizeof(*st)); |
314 | st->f_bsize = buffer_get_int64(&msg); | 314 | st->f_bsize = buffer_get_int64(&msg); |
315 | st->f_frsize = buffer_get_int64(&msg); | 315 | st->f_frsize = buffer_get_int64(&msg); |
316 | st->f_blocks = buffer_get_int64(&msg); | 316 | st->f_blocks = buffer_get_int64(&msg); |
diff --git a/sftp-server.0 b/sftp-server.0 index 5bf8da600..ce7ddc07f 100644 --- a/sftp-server.0 +++ b/sftp-server.0 | |||
@@ -92,4 +92,4 @@ HISTORY | |||
92 | AUTHORS | 92 | AUTHORS |
93 | Markus Friedl <markus@openbsd.org> | 93 | Markus Friedl <markus@openbsd.org> |
94 | 94 | ||
95 | OpenBSD 5.4 October 14, 2013 OpenBSD 5.4 | 95 | OpenBSD 5.5 October 14, 2013 OpenBSD 5.5 |
@@ -367,4 +367,4 @@ SEE ALSO | |||
367 | T. Ylonen and S. Lehtinen, SSH File Transfer Protocol, draft-ietf-secsh- | 367 | T. Ylonen and S. Lehtinen, SSH File Transfer Protocol, draft-ietf-secsh- |
368 | filexfer-00.txt, January 2001, work in progress material. | 368 | filexfer-00.txt, January 2001, work in progress material. |
369 | 369 | ||
370 | OpenBSD 5.4 October 20, 2013 OpenBSD 5.4 | 370 | OpenBSD 5.5 October 20, 2013 OpenBSD 5.5 |
@@ -120,4 +120,4 @@ AUTHORS | |||
120 | created OpenSSH. Markus Friedl contributed the support for SSH protocol | 120 | created OpenSSH. Markus Friedl contributed the support for SSH protocol |
121 | versions 1.5 and 2.0. | 121 | versions 1.5 and 2.0. |
122 | 122 | ||
123 | OpenBSD 5.4 December 7, 2013 OpenBSD 5.4 | 123 | OpenBSD 5.5 December 7, 2013 OpenBSD 5.5 |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh-add.c,v 1.108 2013/12/19 00:10:30 djm Exp $ */ | 1 | /* $OpenBSD: ssh-add.c,v 1.109 2014/02/02 03:44:31 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -90,7 +90,7 @@ static void | |||
90 | clear_pass(void) | 90 | clear_pass(void) |
91 | { | 91 | { |
92 | if (pass) { | 92 | if (pass) { |
93 | memset(pass, 0, strlen(pass)); | 93 | explicit_bzero(pass, strlen(pass)); |
94 | free(pass); | 94 | free(pass); |
95 | pass = NULL; | 95 | pass = NULL; |
96 | } | 96 | } |
@@ -366,7 +366,7 @@ lock_agent(AuthenticationConnection *ac, int lock) | |||
366 | fprintf(stderr, "Passwords do not match.\n"); | 366 | fprintf(stderr, "Passwords do not match.\n"); |
367 | passok = 0; | 367 | passok = 0; |
368 | } | 368 | } |
369 | memset(p2, 0, strlen(p2)); | 369 | explicit_bzero(p2, strlen(p2)); |
370 | free(p2); | 370 | free(p2); |
371 | } | 371 | } |
372 | if (passok && ssh_lock_agent(ac, lock, p1)) { | 372 | if (passok && ssh_lock_agent(ac, lock, p1)) { |
@@ -374,7 +374,7 @@ lock_agent(AuthenticationConnection *ac, int lock) | |||
374 | ret = 0; | 374 | ret = 0; |
375 | } else | 375 | } else |
376 | fprintf(stderr, "Failed to %slock agent.\n", lock ? "" : "un"); | 376 | fprintf(stderr, "Failed to %slock agent.\n", lock ? "" : "un"); |
377 | memset(p1, 0, strlen(p1)); | 377 | explicit_bzero(p1, strlen(p1)); |
378 | free(p1); | 378 | free(p1); |
379 | return (ret); | 379 | return (ret); |
380 | } | 380 | } |
diff --git a/ssh-agent.0 b/ssh-agent.0 index c4c53ef94..c11523db3 100644 --- a/ssh-agent.0 +++ b/ssh-agent.0 | |||
@@ -125,4 +125,4 @@ AUTHORS | |||
125 | created OpenSSH. Markus Friedl contributed the support for SSH protocol | 125 | created OpenSSH. Markus Friedl contributed the support for SSH protocol |
126 | versions 1.5 and 2.0. | 126 | versions 1.5 and 2.0. |
127 | 127 | ||
128 | OpenBSD 5.4 December 7, 2013 OpenBSD 5.4 | 128 | OpenBSD 5.5 December 7, 2013 OpenBSD 5.5 |
diff --git a/ssh-agent.c b/ssh-agent.c index 95117e076..ba2461211 100644 --- a/ssh-agent.c +++ b/ssh-agent.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh-agent.c,v 1.181 2013/12/19 01:19:41 djm Exp $ */ | 1 | /* $OpenBSD: ssh-agent.c,v 1.183 2014/02/02 03:44:31 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -50,7 +50,6 @@ | |||
50 | #include "openbsd-compat/sys-queue.h" | 50 | #include "openbsd-compat/sys-queue.h" |
51 | 51 | ||
52 | #include <openssl/evp.h> | 52 | #include <openssl/evp.h> |
53 | #include <openssl/md5.h> | ||
54 | #include "openbsd-compat/openssl-compat.h" | 53 | #include "openbsd-compat/openssl-compat.h" |
55 | 54 | ||
56 | #include <errno.h> | 55 | #include <errno.h> |
@@ -75,6 +74,7 @@ | |||
75 | #include "compat.h" | 74 | #include "compat.h" |
76 | #include "log.h" | 75 | #include "log.h" |
77 | #include "misc.h" | 76 | #include "misc.h" |
77 | #include "digest.h" | ||
78 | 78 | ||
79 | #ifdef ENABLE_PKCS11 | 79 | #ifdef ENABLE_PKCS11 |
80 | #include "ssh-pkcs11.h" | 80 | #include "ssh-pkcs11.h" |
@@ -248,7 +248,7 @@ process_authentication_challenge1(SocketEntry *e) | |||
248 | Identity *id; | 248 | Identity *id; |
249 | int i, len; | 249 | int i, len; |
250 | Buffer msg; | 250 | Buffer msg; |
251 | MD5_CTX md; | 251 | struct ssh_digest_ctx *md; |
252 | Key *key; | 252 | Key *key; |
253 | 253 | ||
254 | buffer_init(&msg); | 254 | buffer_init(&msg); |
@@ -284,10 +284,12 @@ process_authentication_challenge1(SocketEntry *e) | |||
284 | } | 284 | } |
285 | memset(buf, 0, 32); | 285 | memset(buf, 0, 32); |
286 | BN_bn2bin(challenge, buf + 32 - len); | 286 | BN_bn2bin(challenge, buf + 32 - len); |
287 | MD5_Init(&md); | 287 | if ((md = ssh_digest_start(SSH_DIGEST_MD5)) == NULL || |
288 | MD5_Update(&md, buf, 32); | 288 | ssh_digest_update(md, buf, 32) < 0 || |
289 | MD5_Update(&md, session_id, 16); | 289 | ssh_digest_update(md, session_id, 16) < 0 || |
290 | MD5_Final(mdbuf, &md); | 290 | ssh_digest_final(md, mdbuf, sizeof(mdbuf)) < 0) |
291 | fatal("%s: md5 failed", __func__); | ||
292 | ssh_digest_free(md); | ||
291 | 293 | ||
292 | /* Send the response. */ | 294 | /* Send the response. */ |
293 | buffer_put_char(&msg, SSH_AGENT_RSA_RESPONSE); | 295 | buffer_put_char(&msg, SSH_AGENT_RSA_RESPONSE); |
@@ -552,7 +554,7 @@ process_lock_agent(SocketEntry *e, int lock) | |||
552 | passwd = buffer_get_string(&e->request, NULL); | 554 | passwd = buffer_get_string(&e->request, NULL); |
553 | if (locked && !lock && strcmp(passwd, lock_passwd) == 0) { | 555 | if (locked && !lock && strcmp(passwd, lock_passwd) == 0) { |
554 | locked = 0; | 556 | locked = 0; |
555 | memset(lock_passwd, 0, strlen(lock_passwd)); | 557 | explicit_bzero(lock_passwd, strlen(lock_passwd)); |
556 | free(lock_passwd); | 558 | free(lock_passwd); |
557 | lock_passwd = NULL; | 559 | lock_passwd = NULL; |
558 | success = 1; | 560 | success = 1; |
@@ -561,7 +563,7 @@ process_lock_agent(SocketEntry *e, int lock) | |||
561 | lock_passwd = xstrdup(passwd); | 563 | lock_passwd = xstrdup(passwd); |
562 | success = 1; | 564 | success = 1; |
563 | } | 565 | } |
564 | memset(passwd, 0, strlen(passwd)); | 566 | explicit_bzero(passwd, strlen(passwd)); |
565 | free(passwd); | 567 | free(passwd); |
566 | 568 | ||
567 | buffer_put_int(&e->output, 1); | 569 | buffer_put_int(&e->output, 1); |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh-dss.c,v 1.30 2014/01/09 23:20:00 djm Exp $ */ | 1 | /* $OpenBSD: ssh-dss.c,v 1.31 2014/02/02 03:44:31 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -65,7 +65,7 @@ ssh_dss_sign(const Key *key, u_char **sigp, u_int *lenp, | |||
65 | } | 65 | } |
66 | 66 | ||
67 | sig = DSA_do_sign(digest, dlen, key->dsa); | 67 | sig = DSA_do_sign(digest, dlen, key->dsa); |
68 | memset(digest, 'd', sizeof(digest)); | 68 | explicit_bzero(digest, sizeof(digest)); |
69 | 69 | ||
70 | if (sig == NULL) { | 70 | if (sig == NULL) { |
71 | error("ssh_dss_sign: sign failed"); | 71 | error("ssh_dss_sign: sign failed"); |
@@ -79,7 +79,7 @@ ssh_dss_sign(const Key *key, u_char **sigp, u_int *lenp, | |||
79 | DSA_SIG_free(sig); | 79 | DSA_SIG_free(sig); |
80 | return -1; | 80 | return -1; |
81 | } | 81 | } |
82 | memset(sigblob, 0, SIGBLOB_LEN); | 82 | explicit_bzero(sigblob, SIGBLOB_LEN); |
83 | BN_bn2bin(sig->r, sigblob+ SIGBLOB_LEN - INTBLOB_LEN - rlen); | 83 | BN_bn2bin(sig->r, sigblob+ SIGBLOB_LEN - INTBLOB_LEN - rlen); |
84 | BN_bn2bin(sig->s, sigblob+ SIGBLOB_LEN - slen); | 84 | BN_bn2bin(sig->s, sigblob+ SIGBLOB_LEN - slen); |
85 | DSA_SIG_free(sig); | 85 | DSA_SIG_free(sig); |
@@ -168,7 +168,7 @@ ssh_dss_verify(const Key *key, const u_char *signature, u_int signaturelen, | |||
168 | fatal("%s: BN_bin2bn failed", __func__); | 168 | fatal("%s: BN_bin2bn failed", __func__); |
169 | 169 | ||
170 | /* clean up */ | 170 | /* clean up */ |
171 | memset(sigblob, 0, len); | 171 | explicit_bzero(sigblob, len); |
172 | free(sigblob); | 172 | free(sigblob); |
173 | 173 | ||
174 | /* sha1 the data */ | 174 | /* sha1 the data */ |
@@ -179,7 +179,7 @@ ssh_dss_verify(const Key *key, const u_char *signature, u_int signaturelen, | |||
179 | } | 179 | } |
180 | 180 | ||
181 | ret = DSA_do_verify(digest, dlen, sig, key->dsa); | 181 | ret = DSA_do_verify(digest, dlen, sig, key->dsa); |
182 | memset(digest, 'd', sizeof(digest)); | 182 | explicit_bzero(digest, sizeof(digest)); |
183 | 183 | ||
184 | DSA_SIG_free(sig); | 184 | DSA_SIG_free(sig); |
185 | 185 | ||
diff --git a/ssh-ecdsa.c b/ssh-ecdsa.c index 10ad9da60..551c9c460 100644 --- a/ssh-ecdsa.c +++ b/ssh-ecdsa.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh-ecdsa.c,v 1.8 2014/01/09 23:20:00 djm Exp $ */ | 1 | /* $OpenBSD: ssh-ecdsa.c,v 1.10 2014/02/03 23:28:00 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
4 | * Copyright (c) 2010 Damien Miller. All rights reserved. | 4 | * Copyright (c) 2010 Damien Miller. All rights reserved. |
@@ -72,7 +72,7 @@ ssh_ecdsa_sign(const Key *key, u_char **sigp, u_int *lenp, | |||
72 | } | 72 | } |
73 | 73 | ||
74 | sig = ECDSA_do_sign(digest, dlen, key->ecdsa); | 74 | sig = ECDSA_do_sign(digest, dlen, key->ecdsa); |
75 | memset(digest, 'd', sizeof(digest)); | 75 | explicit_bzero(digest, sizeof(digest)); |
76 | 76 | ||
77 | if (sig == NULL) { | 77 | if (sig == NULL) { |
78 | error("%s: sign failed", __func__); | 78 | error("%s: sign failed", __func__); |
@@ -140,9 +140,6 @@ ssh_ecdsa_verify(const Key *key, const u_char *signature, u_int signaturelen, | |||
140 | /* parse signature */ | 140 | /* parse signature */ |
141 | if ((sig = ECDSA_SIG_new()) == NULL) | 141 | if ((sig = ECDSA_SIG_new()) == NULL) |
142 | fatal("%s: ECDSA_SIG_new failed", __func__); | 142 | fatal("%s: ECDSA_SIG_new failed", __func__); |
143 | if ((sig->r = BN_new()) == NULL || | ||
144 | (sig->s = BN_new()) == NULL) | ||
145 | fatal("%s: BN_new failed", __func__); | ||
146 | 143 | ||
147 | buffer_init(&bb); | 144 | buffer_init(&bb); |
148 | buffer_append(&bb, sigblob, len); | 145 | buffer_append(&bb, sigblob, len); |
@@ -153,7 +150,7 @@ ssh_ecdsa_verify(const Key *key, const u_char *signature, u_int signaturelen, | |||
153 | buffer_free(&bb); | 150 | buffer_free(&bb); |
154 | 151 | ||
155 | /* clean up */ | 152 | /* clean up */ |
156 | memset(sigblob, 0, len); | 153 | explicit_bzero(sigblob, len); |
157 | free(sigblob); | 154 | free(sigblob); |
158 | 155 | ||
159 | /* hash the data */ | 156 | /* hash the data */ |
@@ -169,7 +166,7 @@ ssh_ecdsa_verify(const Key *key, const u_char *signature, u_int signaturelen, | |||
169 | } | 166 | } |
170 | 167 | ||
171 | ret = ECDSA_do_verify(digest, dlen, sig, key->ecdsa); | 168 | ret = ECDSA_do_verify(digest, dlen, sig, key->ecdsa); |
172 | memset(digest, 'd', sizeof(digest)); | 169 | explicit_bzero(digest, sizeof(digest)); |
173 | 170 | ||
174 | ECDSA_SIG_free(sig); | 171 | ECDSA_SIG_free(sig); |
175 | 172 | ||
diff --git a/ssh-ed25519.c b/ssh-ed25519.c index 1aedcf83a..160d1f23b 100644 --- a/ssh-ed25519.c +++ b/ssh-ed25519.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh-ed25519.c,v 1.1 2013/12/06 13:39:49 markus Exp $ */ | 1 | /* $OpenBSD: ssh-ed25519.c,v 1.3 2014/02/23 20:03:42 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2013 Markus Friedl <markus@openbsd.org> | 3 | * Copyright (c) 2013 Markus Friedl <markus@openbsd.org> |
4 | * | 4 | * |
@@ -21,6 +21,7 @@ | |||
21 | 21 | ||
22 | #include "crypto_api.h" | 22 | #include "crypto_api.h" |
23 | 23 | ||
24 | #include <limits.h> | ||
24 | #include <string.h> | 25 | #include <string.h> |
25 | #include <stdarg.h> | 26 | #include <stdarg.h> |
26 | 27 | ||
@@ -45,6 +46,11 @@ ssh_ed25519_sign(const Key *key, u_char **sigp, u_int *lenp, | |||
45 | error("%s: no ED25519 key", __func__); | 46 | error("%s: no ED25519 key", __func__); |
46 | return -1; | 47 | return -1; |
47 | } | 48 | } |
49 | |||
50 | if (datalen >= UINT_MAX - crypto_sign_ed25519_BYTES) { | ||
51 | error("%s: datalen %u too long", __func__, datalen); | ||
52 | return -1; | ||
53 | } | ||
48 | smlen = slen = datalen + crypto_sign_ed25519_BYTES; | 54 | smlen = slen = datalen + crypto_sign_ed25519_BYTES; |
49 | sig = xmalloc(slen); | 55 | sig = xmalloc(slen); |
50 | 56 | ||
@@ -66,7 +72,7 @@ ssh_ed25519_sign(const Key *key, u_char **sigp, u_int *lenp, | |||
66 | memcpy(*sigp, buffer_ptr(&b), len); | 72 | memcpy(*sigp, buffer_ptr(&b), len); |
67 | } | 73 | } |
68 | buffer_free(&b); | 74 | buffer_free(&b); |
69 | memset(sig, 's', slen); | 75 | explicit_bzero(sig, slen); |
70 | free(sig); | 76 | free(sig); |
71 | 77 | ||
72 | return 0; | 78 | return 0; |
@@ -130,9 +136,9 @@ ssh_ed25519_verify(const Key *key, const u_char *signature, u_int signaturelen, | |||
130 | } | 136 | } |
131 | /* XXX compare 'm' and 'data' ? */ | 137 | /* XXX compare 'm' and 'data' ? */ |
132 | 138 | ||
133 | memset(sigblob, 's', len); | 139 | explicit_bzero(sigblob, len); |
134 | memset(sm, 'S', smlen); | 140 | explicit_bzero(sm, smlen); |
135 | memset(m, 'm', smlen); /* NB. mlen may be invalid if ret != 0 */ | 141 | explicit_bzero(m, smlen); /* NB. mlen may be invalid if ret != 0 */ |
136 | free(sigblob); | 142 | free(sigblob); |
137 | free(sm); | 143 | free(sm); |
138 | free(m); | 144 | free(m); |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh-gss.h,v 1.10 2007/06/12 08:20:00 djm Exp $ */ | 1 | /* $OpenBSD: ssh-gss.h,v 1.11 2014/02/26 20:28:44 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. | 3 | * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. |
4 | * | 4 | * |
@@ -104,6 +104,8 @@ void ssh_gssapi_set_oid_data(Gssctxt *, void *, size_t); | |||
104 | void ssh_gssapi_set_oid(Gssctxt *, gss_OID); | 104 | void ssh_gssapi_set_oid(Gssctxt *, gss_OID); |
105 | void ssh_gssapi_supported_oids(gss_OID_set *); | 105 | void ssh_gssapi_supported_oids(gss_OID_set *); |
106 | ssh_gssapi_mech *ssh_gssapi_get_ctype(Gssctxt *); | 106 | ssh_gssapi_mech *ssh_gssapi_get_ctype(Gssctxt *); |
107 | void ssh_gssapi_prepare_supported_oids(void); | ||
108 | OM_uint32 ssh_gssapi_test_oid_supported(OM_uint32 *, gss_OID, int *); | ||
107 | 109 | ||
108 | OM_uint32 ssh_gssapi_import_name(Gssctxt *, const char *); | 110 | OM_uint32 ssh_gssapi_import_name(Gssctxt *, const char *); |
109 | OM_uint32 ssh_gssapi_init_ctx(Gssctxt *, int, | 111 | OM_uint32 ssh_gssapi_init_ctx(Gssctxt *, int, |
diff --git a/ssh-keygen.0 b/ssh-keygen.0 index a69b37d67..c43678ff0 100644 --- a/ssh-keygen.0 +++ b/ssh-keygen.0 | |||
@@ -4,7 +4,7 @@ NAME | |||
4 | ssh-keygen - authentication key generation, management and conversion | 4 | ssh-keygen - authentication key generation, management and conversion |
5 | 5 | ||
6 | SYNOPSIS | 6 | SYNOPSIS |
7 | ssh-keygen [-q] [-b bits] -t type [-N new_passphrase] [-C comment] | 7 | ssh-keygen [-q] [-b bits] [-t type] [-N new_passphrase] [-C comment] |
8 | [-f output_keyfile] | 8 | [-f output_keyfile] |
9 | ssh-keygen -p [-P old_passphrase] [-N new_passphrase] [-f keyfile] | 9 | ssh-keygen -p [-P old_passphrase] [-N new_passphrase] [-f keyfile] |
10 | ssh-keygen -i [-m key_format] [-f input_keyfile] | 10 | ssh-keygen -i [-m key_format] [-f input_keyfile] |
@@ -559,4 +559,4 @@ AUTHORS | |||
559 | created OpenSSH. Markus Friedl contributed the support for SSH protocol | 559 | created OpenSSH. Markus Friedl contributed the support for SSH protocol |
560 | versions 1.5 and 2.0. | 560 | versions 1.5 and 2.0. |
561 | 561 | ||
562 | OpenBSD 5.4 December 21, 2013 OpenBSD 5.4 | 562 | OpenBSD 5.5 February 5, 2014 OpenBSD 5.5 |
diff --git a/ssh-keygen.1 b/ssh-keygen.1 index 0e0ed989f..12e00d416 100644 --- a/ssh-keygen.1 +++ b/ssh-keygen.1 | |||
@@ -1,4 +1,4 @@ | |||
1 | .\" $OpenBSD: ssh-keygen.1,v 1.119 2013/12/21 07:10:47 tedu Exp $ | 1 | .\" $OpenBSD: ssh-keygen.1,v 1.120 2014/02/05 20:13:25 naddy Exp $ |
2 | .\" | 2 | .\" |
3 | .\" Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | .\" Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | .\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | .\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -35,7 +35,7 @@ | |||
35 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 35 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
36 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 36 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
37 | .\" | 37 | .\" |
38 | .Dd $Mdocdate: December 21 2013 $ | 38 | .Dd $Mdocdate: February 5 2014 $ |
39 | .Dt SSH-KEYGEN 1 | 39 | .Dt SSH-KEYGEN 1 |
40 | .Os | 40 | .Os |
41 | .Sh NAME | 41 | .Sh NAME |
@@ -46,7 +46,7 @@ | |||
46 | .Nm ssh-keygen | 46 | .Nm ssh-keygen |
47 | .Op Fl q | 47 | .Op Fl q |
48 | .Op Fl b Ar bits | 48 | .Op Fl b Ar bits |
49 | .Fl t Ar type | 49 | .Op Fl t Ar type |
50 | .Op Fl N Ar new_passphrase | 50 | .Op Fl N Ar new_passphrase |
51 | .Op Fl C Ar comment | 51 | .Op Fl C Ar comment |
52 | .Op Fl f Ar output_keyfile | 52 | .Op Fl f Ar output_keyfile |
diff --git a/ssh-keygen.c b/ssh-keygen.c index eae83a461..2a316bcea 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh-keygen.c,v 1.238 2013/12/06 13:39:49 markus Exp $ */ | 1 | /* $OpenBSD: ssh-keygen.c,v 1.241 2014/02/05 20:13:25 naddy Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -267,7 +267,7 @@ load_identity(char *filename) | |||
267 | pass = read_passphrase("Enter passphrase: ", | 267 | pass = read_passphrase("Enter passphrase: ", |
268 | RP_ALLOW_STDIN); | 268 | RP_ALLOW_STDIN); |
269 | prv = key_load_private(filename, pass, NULL); | 269 | prv = key_load_private(filename, pass, NULL); |
270 | memset(pass, 0, strlen(pass)); | 270 | explicit_bzero(pass, strlen(pass)); |
271 | free(pass); | 271 | free(pass); |
272 | } | 272 | } |
273 | return prv; | 273 | return prv; |
@@ -1258,7 +1258,7 @@ do_change_passphrase(struct passwd *pw) | |||
1258 | RP_ALLOW_STDIN); | 1258 | RP_ALLOW_STDIN); |
1259 | private = key_load_private(identity_file, old_passphrase, | 1259 | private = key_load_private(identity_file, old_passphrase, |
1260 | &comment); | 1260 | &comment); |
1261 | memset(old_passphrase, 0, strlen(old_passphrase)); | 1261 | explicit_bzero(old_passphrase, strlen(old_passphrase)); |
1262 | free(old_passphrase); | 1262 | free(old_passphrase); |
1263 | if (private == NULL) { | 1263 | if (private == NULL) { |
1264 | printf("Bad passphrase.\n"); | 1264 | printf("Bad passphrase.\n"); |
@@ -1280,15 +1280,15 @@ do_change_passphrase(struct passwd *pw) | |||
1280 | 1280 | ||
1281 | /* Verify that they are the same. */ | 1281 | /* Verify that they are the same. */ |
1282 | if (strcmp(passphrase1, passphrase2) != 0) { | 1282 | if (strcmp(passphrase1, passphrase2) != 0) { |
1283 | memset(passphrase1, 0, strlen(passphrase1)); | 1283 | explicit_bzero(passphrase1, strlen(passphrase1)); |
1284 | memset(passphrase2, 0, strlen(passphrase2)); | 1284 | explicit_bzero(passphrase2, strlen(passphrase2)); |
1285 | free(passphrase1); | 1285 | free(passphrase1); |
1286 | free(passphrase2); | 1286 | free(passphrase2); |
1287 | printf("Pass phrases do not match. Try again.\n"); | 1287 | printf("Pass phrases do not match. Try again.\n"); |
1288 | exit(1); | 1288 | exit(1); |
1289 | } | 1289 | } |
1290 | /* Destroy the other copy. */ | 1290 | /* Destroy the other copy. */ |
1291 | memset(passphrase2, 0, strlen(passphrase2)); | 1291 | explicit_bzero(passphrase2, strlen(passphrase2)); |
1292 | free(passphrase2); | 1292 | free(passphrase2); |
1293 | } | 1293 | } |
1294 | 1294 | ||
@@ -1296,14 +1296,14 @@ do_change_passphrase(struct passwd *pw) | |||
1296 | if (!key_save_private(private, identity_file, passphrase1, comment, | 1296 | if (!key_save_private(private, identity_file, passphrase1, comment, |
1297 | use_new_format, new_format_cipher, rounds)) { | 1297 | use_new_format, new_format_cipher, rounds)) { |
1298 | printf("Saving the key failed: %s.\n", identity_file); | 1298 | printf("Saving the key failed: %s.\n", identity_file); |
1299 | memset(passphrase1, 0, strlen(passphrase1)); | 1299 | explicit_bzero(passphrase1, strlen(passphrase1)); |
1300 | free(passphrase1); | 1300 | free(passphrase1); |
1301 | key_free(private); | 1301 | key_free(private); |
1302 | free(comment); | 1302 | free(comment); |
1303 | exit(1); | 1303 | exit(1); |
1304 | } | 1304 | } |
1305 | /* Destroy the passphrase and the copy of the key in memory. */ | 1305 | /* Destroy the passphrase and the copy of the key in memory. */ |
1306 | memset(passphrase1, 0, strlen(passphrase1)); | 1306 | explicit_bzero(passphrase1, strlen(passphrase1)); |
1307 | free(passphrase1); | 1307 | free(passphrase1); |
1308 | key_free(private); /* Destroys contents */ | 1308 | key_free(private); /* Destroys contents */ |
1309 | free(comment); | 1309 | free(comment); |
@@ -1375,7 +1375,7 @@ do_change_comment(struct passwd *pw) | |||
1375 | /* Try to load using the passphrase. */ | 1375 | /* Try to load using the passphrase. */ |
1376 | private = key_load_private(identity_file, passphrase, &comment); | 1376 | private = key_load_private(identity_file, passphrase, &comment); |
1377 | if (private == NULL) { | 1377 | if (private == NULL) { |
1378 | memset(passphrase, 0, strlen(passphrase)); | 1378 | explicit_bzero(passphrase, strlen(passphrase)); |
1379 | free(passphrase); | 1379 | free(passphrase); |
1380 | printf("Bad passphrase.\n"); | 1380 | printf("Bad passphrase.\n"); |
1381 | exit(1); | 1381 | exit(1); |
@@ -1396,7 +1396,7 @@ do_change_comment(struct passwd *pw) | |||
1396 | printf("Enter new comment: "); | 1396 | printf("Enter new comment: "); |
1397 | fflush(stdout); | 1397 | fflush(stdout); |
1398 | if (!fgets(new_comment, sizeof(new_comment), stdin)) { | 1398 | if (!fgets(new_comment, sizeof(new_comment), stdin)) { |
1399 | memset(passphrase, 0, strlen(passphrase)); | 1399 | explicit_bzero(passphrase, strlen(passphrase)); |
1400 | key_free(private); | 1400 | key_free(private); |
1401 | exit(1); | 1401 | exit(1); |
1402 | } | 1402 | } |
@@ -1407,13 +1407,13 @@ do_change_comment(struct passwd *pw) | |||
1407 | if (!key_save_private(private, identity_file, passphrase, new_comment, | 1407 | if (!key_save_private(private, identity_file, passphrase, new_comment, |
1408 | use_new_format, new_format_cipher, rounds)) { | 1408 | use_new_format, new_format_cipher, rounds)) { |
1409 | printf("Saving the key failed: %s.\n", identity_file); | 1409 | printf("Saving the key failed: %s.\n", identity_file); |
1410 | memset(passphrase, 0, strlen(passphrase)); | 1410 | explicit_bzero(passphrase, strlen(passphrase)); |
1411 | free(passphrase); | 1411 | free(passphrase); |
1412 | key_free(private); | 1412 | key_free(private); |
1413 | free(comment); | 1413 | free(comment); |
1414 | exit(1); | 1414 | exit(1); |
1415 | } | 1415 | } |
1416 | memset(passphrase, 0, strlen(passphrase)); | 1416 | explicit_bzero(passphrase, strlen(passphrase)); |
1417 | free(passphrase); | 1417 | free(passphrase); |
1418 | public = key_from_private(private); | 1418 | public = key_from_private(private); |
1419 | key_free(private); | 1419 | key_free(private); |
@@ -1716,7 +1716,7 @@ parse_absolute_time(const char *s) | |||
1716 | fatal("Invalid certificate time format %s", s); | 1716 | fatal("Invalid certificate time format %s", s); |
1717 | } | 1717 | } |
1718 | 1718 | ||
1719 | bzero(&tm, sizeof(tm)); | 1719 | memset(&tm, 0, sizeof(tm)); |
1720 | if (strptime(buf, fmt, &tm) == NULL) | 1720 | if (strptime(buf, fmt, &tm) == NULL) |
1721 | fatal("Invalid certificate time %s", s); | 1721 | fatal("Invalid certificate time %s", s); |
1722 | if ((tt = mktime(&tm)) < 0) | 1722 | if ((tt = mktime(&tm)) < 0) |
@@ -2196,8 +2196,8 @@ usage(void) | |||
2196 | fprintf(stderr, " -v Verbose.\n"); | 2196 | fprintf(stderr, " -v Verbose.\n"); |
2197 | fprintf(stderr, " -W gen Generator to use for generating DH-GEX moduli.\n"); | 2197 | fprintf(stderr, " -W gen Generator to use for generating DH-GEX moduli.\n"); |
2198 | fprintf(stderr, " -y Read private key file and print public key.\n"); | 2198 | fprintf(stderr, " -y Read private key file and print public key.\n"); |
2199 | fprintf(stderr, " -z serial Specify a serial number.\n"); | ||
2200 | fprintf(stderr, " -Z cipher Specify a cipher for new private key format.\n"); | 2199 | fprintf(stderr, " -Z cipher Specify a cipher for new private key format.\n"); |
2200 | fprintf(stderr, " -z serial Specify a serial number.\n"); | ||
2201 | 2201 | ||
2202 | exit(1); | 2202 | exit(1); |
2203 | } | 2203 | } |
@@ -2632,15 +2632,15 @@ passphrase_again: | |||
2632 | * The passphrases do not match. Clear them and | 2632 | * The passphrases do not match. Clear them and |
2633 | * retry. | 2633 | * retry. |
2634 | */ | 2634 | */ |
2635 | memset(passphrase1, 0, strlen(passphrase1)); | 2635 | explicit_bzero(passphrase1, strlen(passphrase1)); |
2636 | memset(passphrase2, 0, strlen(passphrase2)); | 2636 | explicit_bzero(passphrase2, strlen(passphrase2)); |
2637 | free(passphrase1); | 2637 | free(passphrase1); |
2638 | free(passphrase2); | 2638 | free(passphrase2); |
2639 | printf("Passphrases do not match. Try again.\n"); | 2639 | printf("Passphrases do not match. Try again.\n"); |
2640 | goto passphrase_again; | 2640 | goto passphrase_again; |
2641 | } | 2641 | } |
2642 | /* Clear the other copy of the passphrase. */ | 2642 | /* Clear the other copy of the passphrase. */ |
2643 | memset(passphrase2, 0, strlen(passphrase2)); | 2643 | explicit_bzero(passphrase2, strlen(passphrase2)); |
2644 | free(passphrase2); | 2644 | free(passphrase2); |
2645 | } | 2645 | } |
2646 | 2646 | ||
@@ -2655,12 +2655,12 @@ passphrase_again: | |||
2655 | if (!key_save_private(private, identity_file, passphrase1, comment, | 2655 | if (!key_save_private(private, identity_file, passphrase1, comment, |
2656 | use_new_format, new_format_cipher, rounds)) { | 2656 | use_new_format, new_format_cipher, rounds)) { |
2657 | printf("Saving the key failed: %s.\n", identity_file); | 2657 | printf("Saving the key failed: %s.\n", identity_file); |
2658 | memset(passphrase1, 0, strlen(passphrase1)); | 2658 | explicit_bzero(passphrase1, strlen(passphrase1)); |
2659 | free(passphrase1); | 2659 | free(passphrase1); |
2660 | exit(1); | 2660 | exit(1); |
2661 | } | 2661 | } |
2662 | /* Clear the passphrase. */ | 2662 | /* Clear the passphrase. */ |
2663 | memset(passphrase1, 0, strlen(passphrase1)); | 2663 | explicit_bzero(passphrase1, strlen(passphrase1)); |
2664 | free(passphrase1); | 2664 | free(passphrase1); |
2665 | 2665 | ||
2666 | /* Clear the private key and the random number generator. */ | 2666 | /* Clear the private key and the random number generator. */ |
diff --git a/ssh-keyscan.0 b/ssh-keyscan.0 index 09cfa0afa..638c19b48 100644 --- a/ssh-keyscan.0 +++ b/ssh-keyscan.0 | |||
@@ -27,9 +27,10 @@ DESCRIPTION | |||
27 | -6 Forces ssh-keyscan to use IPv6 addresses only. | 27 | -6 Forces ssh-keyscan to use IPv6 addresses only. |
28 | 28 | ||
29 | -f file | 29 | -f file |
30 | Read hosts or addrlist namelist pairs from this file, one per | 30 | Read hosts or ``addrlist namelist'' pairs from file, one per |
31 | line. If - is supplied instead of a filename, ssh-keyscan will | 31 | line. If - is supplied instead of a filename, ssh-keyscan will |
32 | read hosts or addrlist namelist pairs from the standard input. | 32 | read hosts or ``addrlist namelist'' pairs from the standard |
33 | input. | ||
33 | 34 | ||
34 | -H Hash all hostnames and addresses in the output. Hashed names may | 35 | -H Hash all hostnames and addresses in the output. Hashed names may |
35 | be used normally by ssh and sshd, but they do not reveal | 36 | be used normally by ssh and sshd, but they do not reveal |
@@ -106,4 +107,4 @@ BUGS | |||
106 | This is because it opens a connection to the ssh port, reads the public | 107 | This is because it opens a connection to the ssh port, reads the public |
107 | key, and drops the connection as soon as it gets the key. | 108 | key, and drops the connection as soon as it gets the key. |
108 | 109 | ||
109 | OpenBSD 5.4 December 7, 2013 OpenBSD 5.4 | 110 | OpenBSD 5.5 January 28, 2014 OpenBSD 5.5 |
diff --git a/ssh-keyscan.1 b/ssh-keyscan.1 index 65ef43efd..dae4fd9fb 100644 --- a/ssh-keyscan.1 +++ b/ssh-keyscan.1 | |||
@@ -1,4 +1,4 @@ | |||
1 | .\" $OpenBSD: ssh-keyscan.1,v 1.33 2013/12/07 11:58:46 naddy Exp $ | 1 | .\" $OpenBSD: ssh-keyscan.1,v 1.34 2014/01/28 14:13:39 jmc Exp $ |
2 | .\" | 2 | .\" |
3 | .\" Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>. | 3 | .\" Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>. |
4 | .\" | 4 | .\" |
@@ -6,7 +6,7 @@ | |||
6 | .\" permitted provided that due credit is given to the author and the | 6 | .\" permitted provided that due credit is given to the author and the |
7 | .\" OpenBSD project by leaving this copyright notice intact. | 7 | .\" OpenBSD project by leaving this copyright notice intact. |
8 | .\" | 8 | .\" |
9 | .Dd $Mdocdate: December 7 2013 $ | 9 | .Dd $Mdocdate: January 28 2014 $ |
10 | .Dt SSH-KEYSCAN 1 | 10 | .Dt SSH-KEYSCAN 1 |
11 | .Os | 11 | .Os |
12 | .Sh NAME | 12 | .Sh NAME |
@@ -56,14 +56,16 @@ Forces | |||
56 | to use IPv6 addresses only. | 56 | to use IPv6 addresses only. |
57 | .It Fl f Ar file | 57 | .It Fl f Ar file |
58 | Read hosts or | 58 | Read hosts or |
59 | .Pa addrlist namelist | 59 | .Dq addrlist namelist |
60 | pairs from this file, one per line. | 60 | pairs from |
61 | .Ar file , | ||
62 | one per line. | ||
61 | If | 63 | If |
62 | .Pa - | 64 | .Pa - |
63 | is supplied instead of a filename, | 65 | is supplied instead of a filename, |
64 | .Nm | 66 | .Nm |
65 | will read hosts or | 67 | will read hosts or |
66 | .Pa addrlist namelist | 68 | .Dq addrlist namelist |
67 | pairs from the standard input. | 69 | pairs from the standard input. |
68 | .It Fl H | 70 | .It Fl H |
69 | Hash all hostnames and addresses in the output. | 71 | Hash all hostnames and addresses in the output. |
@@ -78,7 +80,7 @@ Port to connect to on the remote host. | |||
78 | .It Fl T Ar timeout | 80 | .It Fl T Ar timeout |
79 | Set the timeout for connection attempts. | 81 | Set the timeout for connection attempts. |
80 | If | 82 | If |
81 | .Pa timeout | 83 | .Ar timeout |
82 | seconds have elapsed since a connection was initiated to a host or since the | 84 | seconds have elapsed since a connection was initiated to a host or since the |
83 | last time anything was read from that host, then the connection is | 85 | last time anything was read from that host, then the connection is |
84 | closed and the host in question considered unavailable. | 86 | closed and the host in question considered unavailable. |
@@ -117,23 +119,23 @@ On the other hand, if the security model allows such a risk, | |||
117 | can help in the detection of tampered keyfiles or man in the middle | 119 | can help in the detection of tampered keyfiles or man in the middle |
118 | attacks which have begun after the ssh_known_hosts file was created. | 120 | attacks which have begun after the ssh_known_hosts file was created. |
119 | .Sh FILES | 121 | .Sh FILES |
120 | .Pa Input format: | 122 | Input format: |
121 | .Bd -literal | 123 | .Bd -literal |
122 | 1.2.3.4,1.2.4.4 name.my.domain,name,n.my.domain,n,1.2.3.4,1.2.4.4 | 124 | 1.2.3.4,1.2.4.4 name.my.domain,name,n.my.domain,n,1.2.3.4,1.2.4.4 |
123 | .Ed | 125 | .Ed |
124 | .Pp | 126 | .Pp |
125 | .Pa Output format for rsa1 keys: | 127 | Output format for rsa1 keys: |
126 | .Bd -literal | 128 | .Bd -literal |
127 | host-or-namelist bits exponent modulus | 129 | host-or-namelist bits exponent modulus |
128 | .Ed | 130 | .Ed |
129 | .Pp | 131 | .Pp |
130 | .Pa Output format for rsa, dsa and ecdsa keys: | 132 | Output format for rsa, dsa and ecdsa keys: |
131 | .Bd -literal | 133 | .Bd -literal |
132 | host-or-namelist keytype base64-encoded-key | 134 | host-or-namelist keytype base64-encoded-key |
133 | .Ed | 135 | .Ed |
134 | .Pp | 136 | .Pp |
135 | Where | 137 | Where |
136 | .Pa keytype | 138 | .Ar keytype |
137 | is either | 139 | is either |
138 | .Dq ecdsa-sha2-nistp256 , | 140 | .Dq ecdsa-sha2-nistp256 , |
139 | .Dq ecdsa-sha2-nistp384 , | 141 | .Dq ecdsa-sha2-nistp384 , |
@@ -145,10 +147,8 @@ or | |||
145 | .Pp | 147 | .Pp |
146 | .Pa /etc/ssh/ssh_known_hosts | 148 | .Pa /etc/ssh/ssh_known_hosts |
147 | .Sh EXAMPLES | 149 | .Sh EXAMPLES |
148 | Print the | 150 | Print the rsa host key for machine |
149 | .Pa rsa | 151 | .Ar hostname : |
150 | host key for machine | ||
151 | .Pa hostname : | ||
152 | .Bd -literal | 152 | .Bd -literal |
153 | $ ssh-keyscan hostname | 153 | $ ssh-keyscan hostname |
154 | .Ed | 154 | .Ed |
diff --git a/ssh-keysign.0 b/ssh-keysign.0 index 78a20e894..5f18b54e3 100644 --- a/ssh-keysign.0 +++ b/ssh-keysign.0 | |||
@@ -50,4 +50,4 @@ HISTORY | |||
50 | AUTHORS | 50 | AUTHORS |
51 | Markus Friedl <markus@openbsd.org> | 51 | Markus Friedl <markus@openbsd.org> |
52 | 52 | ||
53 | OpenBSD 5.4 December 7, 2013 OpenBSD 5.4 | 53 | OpenBSD 5.5 December 7, 2013 OpenBSD 5.5 |
diff --git a/ssh-pkcs11-helper.0 b/ssh-pkcs11-helper.0 index d9ea34248..20d62f7a9 100644 --- a/ssh-pkcs11-helper.0 +++ b/ssh-pkcs11-helper.0 | |||
@@ -22,4 +22,4 @@ HISTORY | |||
22 | AUTHORS | 22 | AUTHORS |
23 | Markus Friedl <markus@openbsd.org> | 23 | Markus Friedl <markus@openbsd.org> |
24 | 24 | ||
25 | OpenBSD 5.4 July 16, 2013 OpenBSD 5.4 | 25 | OpenBSD 5.5 July 16, 2013 OpenBSD 5.5 |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh-rsa.c,v 1.50 2014/01/09 23:20:00 djm Exp $ */ | 1 | /* $OpenBSD: ssh-rsa.c,v 1.51 2014/02/02 03:44:31 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000, 2003 Markus Friedl <markus@openbsd.org> | 3 | * Copyright (c) 2000, 2003 Markus Friedl <markus@openbsd.org> |
4 | * | 4 | * |
@@ -70,7 +70,7 @@ ssh_rsa_sign(const Key *key, u_char **sigp, u_int *lenp, | |||
70 | sig = xmalloc(slen); | 70 | sig = xmalloc(slen); |
71 | 71 | ||
72 | ok = RSA_sign(nid, digest, dlen, sig, &len, key->rsa); | 72 | ok = RSA_sign(nid, digest, dlen, sig, &len, key->rsa); |
73 | memset(digest, 'd', sizeof(digest)); | 73 | explicit_bzero(digest, sizeof(digest)); |
74 | 74 | ||
75 | if (ok != 1) { | 75 | if (ok != 1) { |
76 | int ecode = ERR_get_error(); | 76 | int ecode = ERR_get_error(); |
@@ -84,7 +84,7 @@ ssh_rsa_sign(const Key *key, u_char **sigp, u_int *lenp, | |||
84 | u_int diff = slen - len; | 84 | u_int diff = slen - len; |
85 | debug("slen %u > len %u", slen, len); | 85 | debug("slen %u > len %u", slen, len); |
86 | memmove(sig + diff, sig, len); | 86 | memmove(sig + diff, sig, len); |
87 | memset(sig, 0, diff); | 87 | explicit_bzero(sig, diff); |
88 | } else if (len > slen) { | 88 | } else if (len > slen) { |
89 | error("%s: slen %u slen2 %u", __func__, slen, len); | 89 | error("%s: slen %u slen2 %u", __func__, slen, len); |
90 | free(sig); | 90 | free(sig); |
@@ -102,7 +102,7 @@ ssh_rsa_sign(const Key *key, u_char **sigp, u_int *lenp, | |||
102 | memcpy(*sigp, buffer_ptr(&b), len); | 102 | memcpy(*sigp, buffer_ptr(&b), len); |
103 | } | 103 | } |
104 | buffer_free(&b); | 104 | buffer_free(&b); |
105 | memset(sig, 's', slen); | 105 | explicit_bzero(sig, slen); |
106 | free(sig); | 106 | free(sig); |
107 | 107 | ||
108 | return 0; | 108 | return 0; |
@@ -161,7 +161,7 @@ ssh_rsa_verify(const Key *key, const u_char *signature, u_int signaturelen, | |||
161 | modlen, len); | 161 | modlen, len); |
162 | sigblob = xrealloc(sigblob, 1, modlen); | 162 | sigblob = xrealloc(sigblob, 1, modlen); |
163 | memmove(sigblob + diff, sigblob, len); | 163 | memmove(sigblob + diff, sigblob, len); |
164 | memset(sigblob, 0, diff); | 164 | explicit_bzero(sigblob, diff); |
165 | len = modlen; | 165 | len = modlen; |
166 | } | 166 | } |
167 | /* hash the data */ | 167 | /* hash the data */ |
@@ -178,8 +178,8 @@ ssh_rsa_verify(const Key *key, const u_char *signature, u_int signaturelen, | |||
178 | 178 | ||
179 | ret = openssh_RSA_verify(hash_alg, digest, dlen, sigblob, len, | 179 | ret = openssh_RSA_verify(hash_alg, digest, dlen, sigblob, len, |
180 | key->rsa); | 180 | key->rsa); |
181 | memset(digest, 'd', sizeof(digest)); | 181 | explicit_bzero(digest, sizeof(digest)); |
182 | memset(sigblob, 's', len); | 182 | explicit_bzero(sigblob, len); |
183 | free(sigblob); | 183 | free(sigblob); |
184 | debug("%s: signature %scorrect", __func__, (ret == 0) ? "in" : ""); | 184 | debug("%s: signature %scorrect", __func__, (ret == 0) ? "in" : ""); |
185 | return ret; | 185 | return ret; |
@@ -943,4 +943,4 @@ AUTHORS | |||
943 | created OpenSSH. Markus Friedl contributed the support for SSH protocol | 943 | created OpenSSH. Markus Friedl contributed the support for SSH protocol |
944 | versions 1.5 and 2.0. | 944 | versions 1.5 and 2.0. |
945 | 945 | ||
946 | OpenBSD 5.4 December 7, 2013 OpenBSD 5.4 | 946 | OpenBSD 5.5 December 7, 2013 OpenBSD 5.5 |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh.c,v 1.397 2013/12/29 05:42:16 djm Exp $ */ | 1 | /* $OpenBSD: ssh.c,v 1.401 2014/02/26 20:18:37 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -231,16 +231,26 @@ tilde_expand_paths(char **paths, u_int num_paths) | |||
231 | } | 231 | } |
232 | } | 232 | } |
233 | 233 | ||
234 | /* | ||
235 | * Attempt to resolve a host name / port to a set of addresses and | ||
236 | * optionally return any CNAMEs encountered along the way. | ||
237 | * Returns NULL on failure. | ||
238 | * NB. this function must operate with a options having undefined members. | ||
239 | */ | ||
234 | static struct addrinfo * | 240 | static struct addrinfo * |
235 | resolve_host(const char *name, u_int port, int logerr, char *cname, size_t clen) | 241 | resolve_host(const char *name, int port, int logerr, char *cname, size_t clen) |
236 | { | 242 | { |
237 | char strport[NI_MAXSERV]; | 243 | char strport[NI_MAXSERV]; |
238 | struct addrinfo hints, *res; | 244 | struct addrinfo hints, *res; |
239 | int gaierr, loglevel = SYSLOG_LEVEL_DEBUG1; | 245 | int gaierr, loglevel = SYSLOG_LEVEL_DEBUG1; |
240 | 246 | ||
247 | if (port <= 0) | ||
248 | port = default_ssh_port(); | ||
249 | |||
241 | snprintf(strport, sizeof strport, "%u", port); | 250 | snprintf(strport, sizeof strport, "%u", port); |
242 | bzero(&hints, sizeof(hints)); | 251 | memset(&hints, 0, sizeof(hints)); |
243 | hints.ai_family = options.address_family; | 252 | hints.ai_family = options.address_family == -1 ? |
253 | AF_UNSPEC : options.address_family; | ||
244 | hints.ai_socktype = SOCK_STREAM; | 254 | hints.ai_socktype = SOCK_STREAM; |
245 | if (cname != NULL) | 255 | if (cname != NULL) |
246 | hints.ai_flags = AI_CANONNAME; | 256 | hints.ai_flags = AI_CANONNAME; |
@@ -265,6 +275,7 @@ resolve_host(const char *name, u_int port, int logerr, char *cname, size_t clen) | |||
265 | /* | 275 | /* |
266 | * Check whether the cname is a permitted replacement for the hostname | 276 | * Check whether the cname is a permitted replacement for the hostname |
267 | * and perform the replacement if it is. | 277 | * and perform the replacement if it is. |
278 | * NB. this function must operate with a options having undefined members. | ||
268 | */ | 279 | */ |
269 | static int | 280 | static int |
270 | check_follow_cname(char **namep, const char *cname) | 281 | check_follow_cname(char **namep, const char *cname) |
@@ -281,7 +292,7 @@ check_follow_cname(char **namep, const char *cname) | |||
281 | * Don't attempt to canonicalize names that will be interpreted by | 292 | * Don't attempt to canonicalize names that will be interpreted by |
282 | * a proxy unless the user specifically requests so. | 293 | * a proxy unless the user specifically requests so. |
283 | */ | 294 | */ |
284 | if (options.proxy_command != NULL && | 295 | if (!option_clear_or_none(options.proxy_command) && |
285 | options.canonicalize_hostname != SSH_CANONICALISE_ALWAYS) | 296 | options.canonicalize_hostname != SSH_CANONICALISE_ALWAYS) |
286 | return 0; | 297 | return 0; |
287 | debug3("%s: check \"%s\" CNAME \"%s\"", __func__, *namep, cname); | 298 | debug3("%s: check \"%s\" CNAME \"%s\"", __func__, *namep, cname); |
@@ -305,9 +316,10 @@ check_follow_cname(char **namep, const char *cname) | |||
305 | * Attempt to resolve the supplied hostname after applying the user's | 316 | * Attempt to resolve the supplied hostname after applying the user's |
306 | * canonicalization rules. Returns the address list for the host or NULL | 317 | * canonicalization rules. Returns the address list for the host or NULL |
307 | * if no name was found after canonicalization. | 318 | * if no name was found after canonicalization. |
319 | * NB. this function must operate with a options having undefined members. | ||
308 | */ | 320 | */ |
309 | static struct addrinfo * | 321 | static struct addrinfo * |
310 | resolve_canonicalize(char **hostp, u_int port) | 322 | resolve_canonicalize(char **hostp, int port) |
311 | { | 323 | { |
312 | int i, ndots; | 324 | int i, ndots; |
313 | char *cp, *fullhost, cname_target[NI_MAXHOST]; | 325 | char *cp, *fullhost, cname_target[NI_MAXHOST]; |
@@ -315,13 +327,15 @@ resolve_canonicalize(char **hostp, u_int port) | |||
315 | 327 | ||
316 | if (options.canonicalize_hostname == SSH_CANONICALISE_NO) | 328 | if (options.canonicalize_hostname == SSH_CANONICALISE_NO) |
317 | return NULL; | 329 | return NULL; |
330 | |||
318 | /* | 331 | /* |
319 | * Don't attempt to canonicalize names that will be interpreted by | 332 | * Don't attempt to canonicalize names that will be interpreted by |
320 | * a proxy unless the user specifically requests so. | 333 | * a proxy unless the user specifically requests so. |
321 | */ | 334 | */ |
322 | if (options.proxy_command != NULL && | 335 | if (!option_clear_or_none(options.proxy_command) && |
323 | options.canonicalize_hostname != SSH_CANONICALISE_ALWAYS) | 336 | options.canonicalize_hostname != SSH_CANONICALISE_ALWAYS) |
324 | return NULL; | 337 | return NULL; |
338 | |||
325 | /* Don't apply canonicalization to sufficiently-qualified hostnames */ | 339 | /* Don't apply canonicalization to sufficiently-qualified hostnames */ |
326 | ndots = 0; | 340 | ndots = 0; |
327 | for (cp = *hostp; *cp != '\0'; cp++) { | 341 | for (cp = *hostp; *cp != '\0'; cp++) { |
@@ -338,7 +352,9 @@ resolve_canonicalize(char **hostp, u_int port) | |||
338 | *cname_target = '\0'; | 352 | *cname_target = '\0'; |
339 | xasprintf(&fullhost, "%s.%s.", *hostp, | 353 | xasprintf(&fullhost, "%s.%s.", *hostp, |
340 | options.canonical_domains[i]); | 354 | options.canonical_domains[i]); |
341 | if ((addrs = resolve_host(fullhost, options.port, 0, | 355 | debug3("%s: attempting \"%s\" => \"%s\"", __func__, |
356 | *hostp, fullhost); | ||
357 | if ((addrs = resolve_host(fullhost, port, 0, | ||
342 | cname_target, sizeof(cname_target))) == NULL) { | 358 | cname_target, sizeof(cname_target))) == NULL) { |
343 | free(fullhost); | 359 | free(fullhost); |
344 | continue; | 360 | continue; |
@@ -355,11 +371,41 @@ resolve_canonicalize(char **hostp, u_int port) | |||
355 | return addrs; | 371 | return addrs; |
356 | } | 372 | } |
357 | if (!options.canonicalize_fallback_local) | 373 | if (!options.canonicalize_fallback_local) |
358 | fatal("%s: Could not resolve host \"%s\"", __progname, host); | 374 | fatal("%s: Could not resolve host \"%s\"", __progname, *hostp); |
375 | debug2("%s: host %s not found in any suffix", __func__, *hostp); | ||
359 | return NULL; | 376 | return NULL; |
360 | } | 377 | } |
361 | 378 | ||
362 | /* | 379 | /* |
380 | * Read per-user configuration file. Ignore the system wide config | ||
381 | * file if the user specifies a config file on the command line. | ||
382 | */ | ||
383 | static void | ||
384 | process_config_files(struct passwd *pw) | ||
385 | { | ||
386 | char buf[MAXPATHLEN]; | ||
387 | int r; | ||
388 | |||
389 | if (config != NULL) { | ||
390 | if (strcasecmp(config, "none") != 0 && | ||
391 | !read_config_file(config, pw, host, &options, | ||
392 | SSHCONF_USERCONF)) | ||
393 | fatal("Can't open user config file %.100s: " | ||
394 | "%.100s", config, strerror(errno)); | ||
395 | } else { | ||
396 | r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir, | ||
397 | _PATH_SSH_USER_CONFFILE); | ||
398 | if (r > 0 && (size_t)r < sizeof(buf)) | ||
399 | (void)read_config_file(buf, pw, host, &options, | ||
400 | SSHCONF_CHECKPERM|SSHCONF_USERCONF); | ||
401 | |||
402 | /* Read systemwide configuration file after user config. */ | ||
403 | (void)read_config_file(_PATH_HOST_CONFIG_FILE, pw, host, | ||
404 | &options, 0); | ||
405 | } | ||
406 | } | ||
407 | |||
408 | /* | ||
363 | * Main program for the ssh client. | 409 | * Main program for the ssh client. |
364 | */ | 410 | */ |
365 | int | 411 | int |
@@ -780,7 +826,6 @@ main(int ac, char **av) | |||
780 | if (!host) | 826 | if (!host) |
781 | usage(); | 827 | usage(); |
782 | 828 | ||
783 | lowercase(host); | ||
784 | host_arg = xstrdup(host); | 829 | host_arg = xstrdup(host); |
785 | 830 | ||
786 | OpenSSL_add_all_algorithms(); | 831 | OpenSSL_add_all_algorithms(); |
@@ -833,31 +878,62 @@ main(int ac, char **av) | |||
833 | if (debug_flag) | 878 | if (debug_flag) |
834 | logit("%s, %s", SSH_VERSION, SSLeay_version(SSLEAY_VERSION)); | 879 | logit("%s, %s", SSH_VERSION, SSLeay_version(SSLEAY_VERSION)); |
835 | 880 | ||
881 | /* Parse the configuration files */ | ||
882 | process_config_files(pw); | ||
883 | |||
884 | /* Hostname canonicalisation needs a few options filled. */ | ||
885 | fill_default_options_for_canonicalization(&options); | ||
886 | |||
887 | /* If the user has replaced the hostname then take it into use now */ | ||
888 | if (options.hostname != NULL) { | ||
889 | /* NB. Please keep in sync with readconf.c:match_cfg_line() */ | ||
890 | cp = percent_expand(options.hostname, | ||
891 | "h", host, (char *)NULL); | ||
892 | free(host); | ||
893 | host = cp; | ||
894 | } | ||
895 | |||
896 | /* If canonicalization requested then try to apply it */ | ||
897 | lowercase(host); | ||
898 | if (options.canonicalize_hostname != SSH_CANONICALISE_NO) | ||
899 | addrs = resolve_canonicalize(&host, options.port); | ||
900 | |||
836 | /* | 901 | /* |
837 | * Read per-user configuration file. Ignore the system wide config | 902 | * If CanonicalizePermittedCNAMEs have been specified but |
838 | * file if the user specifies a config file on the command line. | 903 | * other canonicalization did not happen (by not being requested |
904 | * or by failing with fallback) then the hostname may still be changed | ||
905 | * as a result of CNAME following. | ||
906 | * | ||
907 | * Try to resolve the bare hostname name using the system resolver's | ||
908 | * usual search rules and then apply the CNAME follow rules. | ||
909 | * | ||
910 | * Skip the lookup if a ProxyCommand is being used unless the user | ||
911 | * has specifically requested canonicalisation for this case via | ||
912 | * CanonicalizeHostname=always | ||
839 | */ | 913 | */ |
840 | if (config != NULL) { | 914 | if (addrs == NULL && options.num_permitted_cnames != 0 && |
841 | if (strcasecmp(config, "none") != 0 && | 915 | (option_clear_or_none(options.proxy_command) || |
842 | !read_config_file(config, pw, host, &options, | 916 | options.canonicalize_hostname == SSH_CANONICALISE_ALWAYS)) { |
843 | SSHCONF_USERCONF)) | 917 | if ((addrs = resolve_host(host, options.port, 1, |
844 | fatal("Can't open user config file %.100s: " | 918 | cname, sizeof(cname))) == NULL) |
845 | "%.100s", config, strerror(errno)); | 919 | cleanup_exit(255); /* resolve_host logs the error */ |
846 | } else { | 920 | check_follow_cname(&host, cname); |
847 | r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir, | 921 | } |
848 | _PATH_SSH_USER_CONFFILE); | ||
849 | if (r > 0 && (size_t)r < sizeof(buf)) | ||
850 | (void)read_config_file(buf, pw, host, &options, | ||
851 | SSHCONF_CHECKPERM|SSHCONF_USERCONF); | ||
852 | 922 | ||
853 | /* Read systemwide configuration file after user config. */ | 923 | /* |
854 | (void)read_config_file(_PATH_HOST_CONFIG_FILE, pw, host, | 924 | * If the target hostname has changed as a result of canonicalisation |
855 | &options, 0); | 925 | * then re-parse the configuration files as new stanzas may match. |
926 | */ | ||
927 | if (strcasecmp(host_arg, host) != 0) { | ||
928 | debug("Hostname has changed; re-reading configuration"); | ||
929 | process_config_files(pw); | ||
856 | } | 930 | } |
857 | 931 | ||
858 | /* Fill configuration defaults. */ | 932 | /* Fill configuration defaults. */ |
859 | fill_default_options(&options); | 933 | fill_default_options(&options); |
860 | 934 | ||
935 | if (options.port == 0) | ||
936 | options.port = default_ssh_port(); | ||
861 | channel_set_af(options.address_family); | 937 | channel_set_af(options.address_family); |
862 | 938 | ||
863 | /* Tidy and check options */ | 939 | /* Tidy and check options */ |
@@ -900,36 +976,6 @@ main(int ac, char **av) | |||
900 | if (options.user == NULL) | 976 | if (options.user == NULL) |
901 | options.user = xstrdup(pw->pw_name); | 977 | options.user = xstrdup(pw->pw_name); |
902 | 978 | ||
903 | /* Get default port if port has not been set. */ | ||
904 | if (options.port == 0) | ||
905 | options.port = default_ssh_port(); | ||
906 | |||
907 | /* preserve host name given on command line for %n expansion */ | ||
908 | if (options.hostname != NULL) { | ||
909 | /* NB. Please keep in sync with readconf.c:match_cfg_line() */ | ||
910 | cp = percent_expand(options.hostname, | ||
911 | "h", host, (char *)NULL); | ||
912 | free(host); | ||
913 | host = cp; | ||
914 | } | ||
915 | |||
916 | /* If canonicalization requested then try to apply it */ | ||
917 | if (options.canonicalize_hostname != SSH_CANONICALISE_NO) | ||
918 | addrs = resolve_canonicalize(&host, options.port); | ||
919 | /* | ||
920 | * If canonicalization not requested, or if it failed then try to | ||
921 | * resolve the bare hostname name using the system resolver's usual | ||
922 | * search rules. Skip the lookup if a ProxyCommand is being used | ||
923 | * unless the user has specifically requested canonicalisation. | ||
924 | */ | ||
925 | if (addrs == NULL && (options.proxy_command == NULL || | ||
926 | options.canonicalize_hostname == SSH_CANONICALISE_ALWAYS)) { | ||
927 | if ((addrs = resolve_host(host, options.port, 1, | ||
928 | cname, sizeof(cname))) == NULL) | ||
929 | cleanup_exit(255); /* resolve_host logs the error */ | ||
930 | check_follow_cname(&host, cname); | ||
931 | } | ||
932 | |||
933 | if (gethostname(thishost, sizeof(thishost)) == -1) | 979 | if (gethostname(thishost, sizeof(thishost)) == -1) |
934 | fatal("gethostname: %s", strerror(errno)); | 980 | fatal("gethostname: %s", strerror(errno)); |
935 | strlcpy(shorthost, thishost, sizeof(shorthost)); | 981 | strlcpy(shorthost, thishost, sizeof(shorthost)); |
@@ -962,6 +1008,16 @@ main(int ac, char **av) | |||
962 | if (options.control_path != NULL) | 1008 | if (options.control_path != NULL) |
963 | muxclient(options.control_path); | 1009 | muxclient(options.control_path); |
964 | 1010 | ||
1011 | /* | ||
1012 | * If hostname canonicalisation was not enabled, then we may not | ||
1013 | * have yet resolved the hostname. Do so now. | ||
1014 | */ | ||
1015 | if (addrs == NULL && options.proxy_command == NULL) { | ||
1016 | if ((addrs = resolve_host(host, options.port, 1, | ||
1017 | cname, sizeof(cname))) == NULL) | ||
1018 | cleanup_exit(255); /* resolve_host logs the error */ | ||
1019 | } | ||
1020 | |||
965 | timeout_ms = options.connection_timeout * 1000; | 1021 | timeout_ms = options.connection_timeout * 1000; |
966 | 1022 | ||
967 | /* Open a connection to the remote host. */ | 1023 | /* Open a connection to the remote host. */ |
@@ -1697,8 +1753,8 @@ load_public_identity_files(void) | |||
1697 | #endif /* PKCS11 */ | 1753 | #endif /* PKCS11 */ |
1698 | 1754 | ||
1699 | n_ids = 0; | 1755 | n_ids = 0; |
1700 | bzero(identity_files, sizeof(identity_files)); | 1756 | memset(identity_files, 0, sizeof(identity_files)); |
1701 | bzero(identity_keys, sizeof(identity_keys)); | 1757 | memset(identity_keys, 0, sizeof(identity_keys)); |
1702 | 1758 | ||
1703 | #ifdef ENABLE_PKCS11 | 1759 | #ifdef ENABLE_PKCS11 |
1704 | if (options.pkcs11_provider != NULL && | 1760 | if (options.pkcs11_provider != NULL && |
@@ -1773,9 +1829,9 @@ load_public_identity_files(void) | |||
1773 | memcpy(options.identity_files, identity_files, sizeof(identity_files)); | 1829 | memcpy(options.identity_files, identity_files, sizeof(identity_files)); |
1774 | memcpy(options.identity_keys, identity_keys, sizeof(identity_keys)); | 1830 | memcpy(options.identity_keys, identity_keys, sizeof(identity_keys)); |
1775 | 1831 | ||
1776 | bzero(pwname, strlen(pwname)); | 1832 | explicit_bzero(pwname, strlen(pwname)); |
1777 | free(pwname); | 1833 | free(pwname); |
1778 | bzero(pwdir, strlen(pwdir)); | 1834 | explicit_bzero(pwdir, strlen(pwdir)); |
1779 | free(pwdir); | 1835 | free(pwdir); |
1780 | } | 1836 | } |
1781 | 1837 | ||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh2.h,v 1.14 2010/08/31 11:54:45 djm Exp $ */ | 1 | /* $OpenBSD: ssh2.h,v 1.15 2014/01/29 06:18:35 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 4 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
@@ -115,12 +115,6 @@ | |||
115 | #define SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ 60 | 115 | #define SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ 60 |
116 | #define SSH2_MSG_USERAUTH_INFO_REQUEST 60 | 116 | #define SSH2_MSG_USERAUTH_INFO_REQUEST 60 |
117 | #define SSH2_MSG_USERAUTH_INFO_RESPONSE 61 | 117 | #define SSH2_MSG_USERAUTH_INFO_RESPONSE 61 |
118 | #define SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP1 60 | ||
119 | #define SSH2_MSG_USERAUTH_JPAKE_SERVER_STEP1 61 | ||
120 | #define SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP2 62 | ||
121 | #define SSH2_MSG_USERAUTH_JPAKE_SERVER_STEP2 63 | ||
122 | #define SSH2_MSG_USERAUTH_JPAKE_CLIENT_CONFIRM 64 | ||
123 | #define SSH2_MSG_USERAUTH_JPAKE_SERVER_CONFIRM 65 | ||
124 | 118 | ||
125 | /* connection protocol: generic */ | 119 | /* connection protocol: generic */ |
126 | 120 | ||
diff --git a/ssh_config.0 b/ssh_config.0 index e9ac54bfc..6fbd10d61 100644 --- a/ssh_config.0 +++ b/ssh_config.0 | |||
@@ -128,6 +128,11 @@ DESCRIPTION | |||
128 | set to ``always'', then canonicalization is applied to proxied | 128 | set to ``always'', then canonicalization is applied to proxied |
129 | connections too. | 129 | connections too. |
130 | 130 | ||
131 | If this option is enabled and canonicalisation results in the | ||
132 | target hostname changing, then the configuration files are | ||
133 | processed again using the new target name to pick up any new | ||
134 | configuration in matching Host stanzas. | ||
135 | |||
131 | CanonicalizeMaxDots | 136 | CanonicalizeMaxDots |
132 | Specifies the maximum number of dot characters in a hostname | 137 | Specifies the maximum number of dot characters in a hostname |
133 | before canonicalization is disabled. The default, ``1'', allows | 138 | before canonicalization is disabled. The default, ``1'', allows |
@@ -881,4 +886,4 @@ AUTHORS | |||
881 | created OpenSSH. Markus Friedl contributed the support for SSH protocol | 886 | created OpenSSH. Markus Friedl contributed the support for SSH protocol |
882 | versions 1.5 and 2.0. | 887 | versions 1.5 and 2.0. |
883 | 888 | ||
884 | OpenBSD 5.4 January 19, 2014 OpenBSD 5.4 | 889 | OpenBSD 5.5 February 23, 2014 OpenBSD 5.5 |
diff --git a/ssh_config.5 b/ssh_config.5 index 3cadcd767..b5803920f 100644 --- a/ssh_config.5 +++ b/ssh_config.5 | |||
@@ -33,8 +33,8 @@ | |||
33 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 33 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
34 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 34 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
35 | .\" | 35 | .\" |
36 | .\" $OpenBSD: ssh_config.5,v 1.184 2014/01/19 04:48:08 djm Exp $ | 36 | .\" $OpenBSD: ssh_config.5,v 1.185 2014/02/23 20:11:36 djm Exp $ |
37 | .Dd $Mdocdate: January 19 2014 $ | 37 | .Dd $Mdocdate: February 23 2014 $ |
38 | .Dt SSH_CONFIG 5 | 38 | .Dt SSH_CONFIG 5 |
39 | .Os | 39 | .Os |
40 | .Sh NAME | 40 | .Sh NAME |
@@ -263,6 +263,12 @@ If | |||
263 | is set to | 263 | is set to |
264 | .Dq always , | 264 | .Dq always , |
265 | then canonicalization is applied to proxied connections too. | 265 | then canonicalization is applied to proxied connections too. |
266 | .Pp | ||
267 | If this option is enabled and canonicalisation results in the target hostname | ||
268 | changing, then the configuration files are processed again using the new | ||
269 | target name to pick up any new configuration in matching | ||
270 | .Cm Host | ||
271 | stanzas. | ||
266 | .It Cm CanonicalizeMaxDots | 272 | .It Cm CanonicalizeMaxDots |
267 | Specifies the maximum number of dot characters in a hostname before | 273 | Specifies the maximum number of dot characters in a hostname before |
268 | canonicalization is disabled. | 274 | canonicalization is disabled. |
diff --git a/sshconnect.c b/sshconnect.c index d21781ea4..573d7a8e8 100644 --- a/sshconnect.c +++ b/sshconnect.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshconnect.c,v 1.244 2014/01/09 23:26:48 djm Exp $ */ | 1 | /* $OpenBSD: sshconnect.c,v 1.246 2014/02/06 22:21:01 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -269,7 +269,7 @@ static int | |||
269 | ssh_create_socket(int privileged, struct addrinfo *ai) | 269 | ssh_create_socket(int privileged, struct addrinfo *ai) |
270 | { | 270 | { |
271 | int sock, r, gaierr; | 271 | int sock, r, gaierr; |
272 | struct addrinfo hints, *res; | 272 | struct addrinfo hints, *res = NULL; |
273 | 273 | ||
274 | sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); | 274 | sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); |
275 | if (sock < 0) { | 275 | if (sock < 0) { |
@@ -282,17 +282,19 @@ ssh_create_socket(int privileged, struct addrinfo *ai) | |||
282 | if (options.bind_address == NULL && !privileged) | 282 | if (options.bind_address == NULL && !privileged) |
283 | return sock; | 283 | return sock; |
284 | 284 | ||
285 | memset(&hints, 0, sizeof(hints)); | 285 | if (options.bind_address) { |
286 | hints.ai_family = ai->ai_family; | 286 | memset(&hints, 0, sizeof(hints)); |
287 | hints.ai_socktype = ai->ai_socktype; | 287 | hints.ai_family = ai->ai_family; |
288 | hints.ai_protocol = ai->ai_protocol; | 288 | hints.ai_socktype = ai->ai_socktype; |
289 | hints.ai_flags = AI_PASSIVE; | 289 | hints.ai_protocol = ai->ai_protocol; |
290 | gaierr = getaddrinfo(options.bind_address, NULL, &hints, &res); | 290 | hints.ai_flags = AI_PASSIVE; |
291 | if (gaierr) { | 291 | gaierr = getaddrinfo(options.bind_address, NULL, &hints, &res); |
292 | error("getaddrinfo: %s: %s", options.bind_address, | 292 | if (gaierr) { |
293 | ssh_gai_strerror(gaierr)); | 293 | error("getaddrinfo: %s: %s", options.bind_address, |
294 | close(sock); | 294 | ssh_gai_strerror(gaierr)); |
295 | return -1; | 295 | close(sock); |
296 | return -1; | ||
297 | } | ||
296 | } | 298 | } |
297 | /* | 299 | /* |
298 | * If we are running as root and want to connect to a privileged | 300 | * If we are running as root and want to connect to a privileged |
@@ -300,7 +302,7 @@ ssh_create_socket(int privileged, struct addrinfo *ai) | |||
300 | */ | 302 | */ |
301 | if (privileged) { | 303 | if (privileged) { |
302 | PRIV_START; | 304 | PRIV_START; |
303 | r = bindresvport_sa(sock, res->ai_addr); | 305 | r = bindresvport_sa(sock, res ? res->ai_addr : NULL); |
304 | PRIV_END; | 306 | PRIV_END; |
305 | if (r < 0) { | 307 | if (r < 0) { |
306 | error("bindresvport_sa: af=%d %s", ai->ai_family, | 308 | error("bindresvport_sa: af=%d %s", ai->ai_family, |
@@ -317,7 +319,8 @@ ssh_create_socket(int privileged, struct addrinfo *ai) | |||
317 | return -1; | 319 | return -1; |
318 | } | 320 | } |
319 | } | 321 | } |
320 | freeaddrinfo(res); | 322 | if (res != NULL) |
323 | freeaddrinfo(res); | ||
321 | return sock; | 324 | return sock; |
322 | } | 325 | } |
323 | 326 | ||
@@ -1299,7 +1302,7 @@ ssh_put_password(char *password) | |||
1299 | padded = xcalloc(1, size); | 1302 | padded = xcalloc(1, size); |
1300 | strlcpy(padded, password, size); | 1303 | strlcpy(padded, password, size); |
1301 | packet_put_string(padded, size); | 1304 | packet_put_string(padded, size); |
1302 | memset(padded, 0, size); | 1305 | explicit_bzero(padded, size); |
1303 | free(padded); | 1306 | free(padded); |
1304 | } | 1307 | } |
1305 | 1308 | ||
diff --git a/sshconnect1.c b/sshconnect1.c index 7bd6cb018..921408ec1 100644 --- a/sshconnect1.c +++ b/sshconnect1.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshconnect1.c,v 1.72 2013/09/02 22:00:34 deraadt Exp $ */ | 1 | /* $OpenBSD: sshconnect1.c,v 1.74 2014/02/02 03:44:32 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -19,7 +19,6 @@ | |||
19 | #include <sys/socket.h> | 19 | #include <sys/socket.h> |
20 | 20 | ||
21 | #include <openssl/bn.h> | 21 | #include <openssl/bn.h> |
22 | #include <openssl/md5.h> | ||
23 | 22 | ||
24 | #include <stdarg.h> | 23 | #include <stdarg.h> |
25 | #include <stdio.h> | 24 | #include <stdio.h> |
@@ -47,6 +46,7 @@ | |||
47 | #include "canohost.h" | 46 | #include "canohost.h" |
48 | #include "hostfile.h" | 47 | #include "hostfile.h" |
49 | #include "auth.h" | 48 | #include "auth.h" |
49 | #include "digest.h" | ||
50 | 50 | ||
51 | /* Session id for the current session. */ | 51 | /* Session id for the current session. */ |
52 | u_char session_id[16]; | 52 | u_char session_id[16]; |
@@ -120,7 +120,7 @@ try_agent_authentication(void) | |||
120 | * return a wrong value. | 120 | * return a wrong value. |
121 | */ | 121 | */ |
122 | logit("Authentication agent failed to decrypt challenge."); | 122 | logit("Authentication agent failed to decrypt challenge."); |
123 | memset(response, 0, sizeof(response)); | 123 | explicit_bzero(response, sizeof(response)); |
124 | } | 124 | } |
125 | key_free(key); | 125 | key_free(key); |
126 | debug("Sending response to RSA challenge."); | 126 | debug("Sending response to RSA challenge."); |
@@ -161,7 +161,7 @@ static void | |||
161 | respond_to_rsa_challenge(BIGNUM * challenge, RSA * prv) | 161 | respond_to_rsa_challenge(BIGNUM * challenge, RSA * prv) |
162 | { | 162 | { |
163 | u_char buf[32], response[16]; | 163 | u_char buf[32], response[16]; |
164 | MD5_CTX md; | 164 | struct ssh_digest_ctx *md; |
165 | int i, len; | 165 | int i, len; |
166 | 166 | ||
167 | /* Decrypt the challenge using the private key. */ | 167 | /* Decrypt the challenge using the private key. */ |
@@ -179,10 +179,12 @@ respond_to_rsa_challenge(BIGNUM * challenge, RSA * prv) | |||
179 | 179 | ||
180 | memset(buf, 0, sizeof(buf)); | 180 | memset(buf, 0, sizeof(buf)); |
181 | BN_bn2bin(challenge, buf + sizeof(buf) - len); | 181 | BN_bn2bin(challenge, buf + sizeof(buf) - len); |
182 | MD5_Init(&md); | 182 | if ((md = ssh_digest_start(SSH_DIGEST_MD5)) == NULL || |
183 | MD5_Update(&md, buf, 32); | 183 | ssh_digest_update(md, buf, 32) < 0 || |
184 | MD5_Update(&md, session_id, 16); | 184 | ssh_digest_update(md, session_id, 16) < 0 || |
185 | MD5_Final(response, &md); | 185 | ssh_digest_final(md, response, sizeof(response)) < 0) |
186 | fatal("%s: md5 failed", __func__); | ||
187 | ssh_digest_free(md); | ||
186 | 188 | ||
187 | debug("Sending response to host key RSA challenge."); | 189 | debug("Sending response to host key RSA challenge."); |
188 | 190 | ||
@@ -193,9 +195,9 @@ respond_to_rsa_challenge(BIGNUM * challenge, RSA * prv) | |||
193 | packet_send(); | 195 | packet_send(); |
194 | packet_write_wait(); | 196 | packet_write_wait(); |
195 | 197 | ||
196 | memset(buf, 0, sizeof(buf)); | 198 | explicit_bzero(buf, sizeof(buf)); |
197 | memset(response, 0, sizeof(response)); | 199 | explicit_bzero(response, sizeof(response)); |
198 | memset(&md, 0, sizeof(md)); | 200 | explicit_bzero(&md, sizeof(md)); |
199 | } | 201 | } |
200 | 202 | ||
201 | /* | 203 | /* |
@@ -269,7 +271,7 @@ try_rsa_authentication(int idx) | |||
269 | debug2("no passphrase given, try next key"); | 271 | debug2("no passphrase given, try next key"); |
270 | quit = 1; | 272 | quit = 1; |
271 | } | 273 | } |
272 | memset(passphrase, 0, strlen(passphrase)); | 274 | explicit_bzero(passphrase, strlen(passphrase)); |
273 | free(passphrase); | 275 | free(passphrase); |
274 | if (private != NULL || quit) | 276 | if (private != NULL || quit) |
275 | break; | 277 | break; |
@@ -425,7 +427,7 @@ try_challenge_response_authentication(void) | |||
425 | } | 427 | } |
426 | packet_start(SSH_CMSG_AUTH_TIS_RESPONSE); | 428 | packet_start(SSH_CMSG_AUTH_TIS_RESPONSE); |
427 | ssh_put_password(response); | 429 | ssh_put_password(response); |
428 | memset(response, 0, strlen(response)); | 430 | explicit_bzero(response, strlen(response)); |
429 | free(response); | 431 | free(response); |
430 | packet_send(); | 432 | packet_send(); |
431 | packet_write_wait(); | 433 | packet_write_wait(); |
@@ -458,7 +460,7 @@ try_password_authentication(char *prompt) | |||
458 | password = read_passphrase(prompt, 0); | 460 | password = read_passphrase(prompt, 0); |
459 | packet_start(SSH_CMSG_AUTH_PASSWORD); | 461 | packet_start(SSH_CMSG_AUTH_PASSWORD); |
460 | ssh_put_password(password); | 462 | ssh_put_password(password); |
461 | memset(password, 0, strlen(password)); | 463 | explicit_bzero(password, strlen(password)); |
462 | free(password); | 464 | free(password); |
463 | packet_send(); | 465 | packet_send(); |
464 | packet_write_wait(); | 466 | packet_write_wait(); |
@@ -650,8 +652,11 @@ ssh_kex(char *host, struct sockaddr *hostaddr) | |||
650 | /* Set the encryption key. */ | 652 | /* Set the encryption key. */ |
651 | packet_set_encryption_key(session_key, SSH_SESSION_KEY_LENGTH, options.cipher); | 653 | packet_set_encryption_key(session_key, SSH_SESSION_KEY_LENGTH, options.cipher); |
652 | 654 | ||
653 | /* We will no longer need the session key here. Destroy any extra copies. */ | 655 | /* |
654 | memset(session_key, 0, sizeof(session_key)); | 656 | * We will no longer need the session key here. |
657 | * Destroy any extra copies. | ||
658 | */ | ||
659 | explicit_bzero(session_key, sizeof(session_key)); | ||
655 | 660 | ||
656 | /* | 661 | /* |
657 | * Expect a success message from the server. Note that this message | 662 | * Expect a success message from the server. Note that this message |
diff --git a/sshconnect2.c b/sshconnect2.c index 8acffc5c3..7f4ff4189 100644 --- a/sshconnect2.c +++ b/sshconnect2.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshconnect2.c,v 1.201 2014/01/09 23:20:00 djm Exp $ */ | 1 | /* $OpenBSD: sshconnect2.c,v 1.204 2014/02/02 03:44:32 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
4 | * Copyright (c) 2008 Damien Miller. All rights reserved. | 4 | * Copyright (c) 2008 Damien Miller. All rights reserved. |
@@ -70,8 +70,6 @@ | |||
70 | #include "pathnames.h" | 70 | #include "pathnames.h" |
71 | #include "uidswap.h" | 71 | #include "uidswap.h" |
72 | #include "hostfile.h" | 72 | #include "hostfile.h" |
73 | #include "schnorr.h" | ||
74 | #include "jpake.h" | ||
75 | 73 | ||
76 | #ifdef GSSAPI | 74 | #ifdef GSSAPI |
77 | #include "ssh-gss.h" | 75 | #include "ssh-gss.h" |
@@ -289,18 +287,12 @@ void input_userauth_error(int, u_int32_t, void *); | |||
289 | void input_userauth_info_req(int, u_int32_t, void *); | 287 | void input_userauth_info_req(int, u_int32_t, void *); |
290 | void input_userauth_pk_ok(int, u_int32_t, void *); | 288 | void input_userauth_pk_ok(int, u_int32_t, void *); |
291 | void input_userauth_passwd_changereq(int, u_int32_t, void *); | 289 | void input_userauth_passwd_changereq(int, u_int32_t, void *); |
292 | void input_userauth_jpake_server_step1(int, u_int32_t, void *); | ||
293 | void input_userauth_jpake_server_step2(int, u_int32_t, void *); | ||
294 | void input_userauth_jpake_server_confirm(int, u_int32_t, void *); | ||
295 | 290 | ||
296 | int userauth_none(Authctxt *); | 291 | int userauth_none(Authctxt *); |
297 | int userauth_pubkey(Authctxt *); | 292 | int userauth_pubkey(Authctxt *); |
298 | int userauth_passwd(Authctxt *); | 293 | int userauth_passwd(Authctxt *); |
299 | int userauth_kbdint(Authctxt *); | 294 | int userauth_kbdint(Authctxt *); |
300 | int userauth_hostbased(Authctxt *); | 295 | int userauth_hostbased(Authctxt *); |
301 | int userauth_jpake(Authctxt *); | ||
302 | |||
303 | void userauth_jpake_cleanup(Authctxt *); | ||
304 | 296 | ||
305 | #ifdef GSSAPI | 297 | #ifdef GSSAPI |
306 | int userauth_gssapi(Authctxt *authctxt); | 298 | int userauth_gssapi(Authctxt *authctxt); |
@@ -340,13 +332,6 @@ Authmethod authmethods[] = { | |||
340 | NULL, | 332 | NULL, |
341 | &options.pubkey_authentication, | 333 | &options.pubkey_authentication, |
342 | NULL}, | 334 | NULL}, |
343 | #ifdef JPAKE | ||
344 | {"jpake-01@openssh.com", | ||
345 | userauth_jpake, | ||
346 | userauth_jpake_cleanup, | ||
347 | &options.zero_knowledge_password_authentication, | ||
348 | &options.batch_mode}, | ||
349 | #endif | ||
350 | {"keyboard-interactive", | 335 | {"keyboard-interactive", |
351 | userauth_kbdint, | 336 | userauth_kbdint, |
352 | NULL, | 337 | NULL, |
@@ -884,7 +869,7 @@ userauth_passwd(Authctxt *authctxt) | |||
884 | packet_put_cstring(authctxt->method->name); | 869 | packet_put_cstring(authctxt->method->name); |
885 | packet_put_char(0); | 870 | packet_put_char(0); |
886 | packet_put_cstring(password); | 871 | packet_put_cstring(password); |
887 | memset(password, 0, strlen(password)); | 872 | explicit_bzero(password, strlen(password)); |
888 | free(password); | 873 | free(password); |
889 | packet_add_padding(64); | 874 | packet_add_padding(64); |
890 | packet_send(); | 875 | packet_send(); |
@@ -930,7 +915,7 @@ input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt) | |||
930 | authctxt->server_user, host); | 915 | authctxt->server_user, host); |
931 | password = read_passphrase(prompt, 0); | 916 | password = read_passphrase(prompt, 0); |
932 | packet_put_cstring(password); | 917 | packet_put_cstring(password); |
933 | memset(password, 0, strlen(password)); | 918 | explicit_bzero(password, strlen(password)); |
934 | free(password); | 919 | free(password); |
935 | password = NULL; | 920 | password = NULL; |
936 | while (password == NULL) { | 921 | while (password == NULL) { |
@@ -947,16 +932,16 @@ input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt) | |||
947 | authctxt->server_user, host); | 932 | authctxt->server_user, host); |
948 | retype = read_passphrase(prompt, 0); | 933 | retype = read_passphrase(prompt, 0); |
949 | if (strcmp(password, retype) != 0) { | 934 | if (strcmp(password, retype) != 0) { |
950 | memset(password, 0, strlen(password)); | 935 | explicit_bzero(password, strlen(password)); |
951 | free(password); | 936 | free(password); |
952 | logit("Mismatch; try again, EOF to quit."); | 937 | logit("Mismatch; try again, EOF to quit."); |
953 | password = NULL; | 938 | password = NULL; |
954 | } | 939 | } |
955 | memset(retype, 0, strlen(retype)); | 940 | explicit_bzero(retype, strlen(retype)); |
956 | free(retype); | 941 | free(retype); |
957 | } | 942 | } |
958 | packet_put_cstring(password); | 943 | packet_put_cstring(password); |
959 | memset(password, 0, strlen(password)); | 944 | explicit_bzero(password, strlen(password)); |
960 | free(password); | 945 | free(password); |
961 | packet_add_padding(64); | 946 | packet_add_padding(64); |
962 | packet_send(); | 947 | packet_send(); |
@@ -965,209 +950,6 @@ input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt) | |||
965 | &input_userauth_passwd_changereq); | 950 | &input_userauth_passwd_changereq); |
966 | } | 951 | } |
967 | 952 | ||
968 | #ifdef JPAKE | ||
969 | static char * | ||
970 | pw_encrypt(const char *password, const char *crypt_scheme, const char *salt) | ||
971 | { | ||
972 | /* OpenBSD crypt(3) handles all of these */ | ||
973 | if (strcmp(crypt_scheme, "crypt") == 0 || | ||
974 | strcmp(crypt_scheme, "bcrypt") == 0 || | ||
975 | strcmp(crypt_scheme, "md5crypt") == 0 || | ||
976 | strcmp(crypt_scheme, "crypt-extended") == 0) | ||
977 | return xstrdup(crypt(password, salt)); | ||
978 | error("%s: unsupported password encryption scheme \"%.100s\"", | ||
979 | __func__, crypt_scheme); | ||
980 | return NULL; | ||
981 | } | ||
982 | |||
983 | static BIGNUM * | ||
984 | jpake_password_to_secret(Authctxt *authctxt, const char *crypt_scheme, | ||
985 | const char *salt) | ||
986 | { | ||
987 | char prompt[256], *password, *crypted; | ||
988 | u_char *secret; | ||
989 | u_int secret_len; | ||
990 | BIGNUM *ret; | ||
991 | |||
992 | snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password (JPAKE): ", | ||
993 | authctxt->server_user, authctxt->host); | ||
994 | password = read_passphrase(prompt, 0); | ||
995 | |||
996 | if ((crypted = pw_encrypt(password, crypt_scheme, salt)) == NULL) { | ||
997 | logit("Disabling %s authentication", authctxt->method->name); | ||
998 | authctxt->method->enabled = NULL; | ||
999 | /* Continue with an empty password to fail gracefully */ | ||
1000 | crypted = xstrdup(""); | ||
1001 | } | ||
1002 | |||
1003 | #ifdef JPAKE_DEBUG | ||
1004 | debug3("%s: salt = %s", __func__, salt); | ||
1005 | debug3("%s: scheme = %s", __func__, crypt_scheme); | ||
1006 | debug3("%s: crypted = %s", __func__, crypted); | ||
1007 | #endif | ||
1008 | |||
1009 | if (hash_buffer(crypted, strlen(crypted), SSH_DIGEST_SHA1, | ||
1010 | &secret, &secret_len) != 0) | ||
1011 | fatal("%s: hash_buffer", __func__); | ||
1012 | |||
1013 | bzero(password, strlen(password)); | ||
1014 | bzero(crypted, strlen(crypted)); | ||
1015 | free(password); | ||
1016 | free(crypted); | ||
1017 | |||
1018 | if ((ret = BN_bin2bn(secret, secret_len, NULL)) == NULL) | ||
1019 | fatal("%s: BN_bin2bn (secret)", __func__); | ||
1020 | bzero(secret, secret_len); | ||
1021 | free(secret); | ||
1022 | |||
1023 | return ret; | ||
1024 | } | ||
1025 | |||
1026 | /* ARGSUSED */ | ||
1027 | void | ||
1028 | input_userauth_jpake_server_step1(int type, u_int32_t seq, void *ctxt) | ||
1029 | { | ||
1030 | Authctxt *authctxt = ctxt; | ||
1031 | struct jpake_ctx *pctx = authctxt->methoddata; | ||
1032 | u_char *x3_proof, *x4_proof, *x2_s_proof; | ||
1033 | u_int x3_proof_len, x4_proof_len, x2_s_proof_len; | ||
1034 | char *crypt_scheme, *salt; | ||
1035 | |||
1036 | /* Disable this message */ | ||
1037 | dispatch_set(SSH2_MSG_USERAUTH_JPAKE_SERVER_STEP1, NULL); | ||
1038 | |||
1039 | if ((pctx->g_x3 = BN_new()) == NULL || | ||
1040 | (pctx->g_x4 = BN_new()) == NULL) | ||
1041 | fatal("%s: BN_new", __func__); | ||
1042 | |||
1043 | /* Fetch step 1 values */ | ||
1044 | crypt_scheme = packet_get_string(NULL); | ||
1045 | salt = packet_get_string(NULL); | ||
1046 | pctx->server_id = packet_get_string(&pctx->server_id_len); | ||
1047 | packet_get_bignum2(pctx->g_x3); | ||
1048 | packet_get_bignum2(pctx->g_x4); | ||
1049 | x3_proof = packet_get_string(&x3_proof_len); | ||
1050 | x4_proof = packet_get_string(&x4_proof_len); | ||
1051 | packet_check_eom(); | ||
1052 | |||
1053 | JPAKE_DEBUG_CTX((pctx, "step 1 received in %s", __func__)); | ||
1054 | |||
1055 | /* Obtain password and derive secret */ | ||
1056 | pctx->s = jpake_password_to_secret(authctxt, crypt_scheme, salt); | ||
1057 | bzero(crypt_scheme, strlen(crypt_scheme)); | ||
1058 | bzero(salt, strlen(salt)); | ||
1059 | free(crypt_scheme); | ||
1060 | free(salt); | ||
1061 | JPAKE_DEBUG_BN((pctx->s, "%s: s = ", __func__)); | ||
1062 | |||
1063 | /* Calculate step 2 values */ | ||
1064 | jpake_step2(pctx->grp, pctx->s, pctx->g_x1, | ||
1065 | pctx->g_x3, pctx->g_x4, pctx->x2, | ||
1066 | pctx->server_id, pctx->server_id_len, | ||
1067 | pctx->client_id, pctx->client_id_len, | ||
1068 | x3_proof, x3_proof_len, | ||
1069 | x4_proof, x4_proof_len, | ||
1070 | &pctx->a, | ||
1071 | &x2_s_proof, &x2_s_proof_len); | ||
1072 | |||
1073 | bzero(x3_proof, x3_proof_len); | ||
1074 | bzero(x4_proof, x4_proof_len); | ||
1075 | free(x3_proof); | ||
1076 | free(x4_proof); | ||
1077 | |||
1078 | JPAKE_DEBUG_CTX((pctx, "step 2 sending in %s", __func__)); | ||
1079 | |||
1080 | /* Send values for step 2 */ | ||
1081 | packet_start(SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP2); | ||
1082 | packet_put_bignum2(pctx->a); | ||
1083 | packet_put_string(x2_s_proof, x2_s_proof_len); | ||
1084 | packet_send(); | ||
1085 | |||
1086 | bzero(x2_s_proof, x2_s_proof_len); | ||
1087 | free(x2_s_proof); | ||
1088 | |||
1089 | /* Expect step 2 packet from peer */ | ||
1090 | dispatch_set(SSH2_MSG_USERAUTH_JPAKE_SERVER_STEP2, | ||
1091 | input_userauth_jpake_server_step2); | ||
1092 | } | ||
1093 | |||
1094 | /* ARGSUSED */ | ||
1095 | void | ||
1096 | input_userauth_jpake_server_step2(int type, u_int32_t seq, void *ctxt) | ||
1097 | { | ||
1098 | Authctxt *authctxt = ctxt; | ||
1099 | struct jpake_ctx *pctx = authctxt->methoddata; | ||
1100 | u_char *x4_s_proof; | ||
1101 | u_int x4_s_proof_len; | ||
1102 | |||
1103 | /* Disable this message */ | ||
1104 | dispatch_set(SSH2_MSG_USERAUTH_JPAKE_SERVER_STEP2, NULL); | ||
1105 | |||
1106 | if ((pctx->b = BN_new()) == NULL) | ||
1107 | fatal("%s: BN_new", __func__); | ||
1108 | |||
1109 | /* Fetch step 2 values */ | ||
1110 | packet_get_bignum2(pctx->b); | ||
1111 | x4_s_proof = packet_get_string(&x4_s_proof_len); | ||
1112 | packet_check_eom(); | ||
1113 | |||
1114 | JPAKE_DEBUG_CTX((pctx, "step 2 received in %s", __func__)); | ||
1115 | |||
1116 | /* Derive shared key and calculate confirmation hash */ | ||
1117 | jpake_key_confirm(pctx->grp, pctx->s, pctx->b, | ||
1118 | pctx->x2, pctx->g_x1, pctx->g_x2, pctx->g_x3, pctx->g_x4, | ||
1119 | pctx->client_id, pctx->client_id_len, | ||
1120 | pctx->server_id, pctx->server_id_len, | ||
1121 | session_id2, session_id2_len, | ||
1122 | x4_s_proof, x4_s_proof_len, | ||
1123 | &pctx->k, | ||
1124 | &pctx->h_k_cid_sessid, &pctx->h_k_cid_sessid_len); | ||
1125 | |||
1126 | bzero(x4_s_proof, x4_s_proof_len); | ||
1127 | free(x4_s_proof); | ||
1128 | |||
1129 | JPAKE_DEBUG_CTX((pctx, "confirm sending in %s", __func__)); | ||
1130 | |||
1131 | /* Send key confirmation proof */ | ||
1132 | packet_start(SSH2_MSG_USERAUTH_JPAKE_CLIENT_CONFIRM); | ||
1133 | packet_put_string(pctx->h_k_cid_sessid, pctx->h_k_cid_sessid_len); | ||
1134 | packet_send(); | ||
1135 | |||
1136 | /* Expect confirmation from peer */ | ||
1137 | dispatch_set(SSH2_MSG_USERAUTH_JPAKE_SERVER_CONFIRM, | ||
1138 | input_userauth_jpake_server_confirm); | ||
1139 | } | ||
1140 | |||
1141 | /* ARGSUSED */ | ||
1142 | void | ||
1143 | input_userauth_jpake_server_confirm(int type, u_int32_t seq, void *ctxt) | ||
1144 | { | ||
1145 | Authctxt *authctxt = ctxt; | ||
1146 | struct jpake_ctx *pctx = authctxt->methoddata; | ||
1147 | |||
1148 | /* Disable this message */ | ||
1149 | dispatch_set(SSH2_MSG_USERAUTH_JPAKE_SERVER_CONFIRM, NULL); | ||
1150 | |||
1151 | pctx->h_k_sid_sessid = packet_get_string(&pctx->h_k_sid_sessid_len); | ||
1152 | packet_check_eom(); | ||
1153 | |||
1154 | JPAKE_DEBUG_CTX((pctx, "confirm received in %s", __func__)); | ||
1155 | |||
1156 | /* Verify expected confirmation hash */ | ||
1157 | if (jpake_check_confirm(pctx->k, | ||
1158 | pctx->server_id, pctx->server_id_len, | ||
1159 | session_id2, session_id2_len, | ||
1160 | pctx->h_k_sid_sessid, pctx->h_k_sid_sessid_len) == 1) | ||
1161 | debug("%s: %s success", __func__, authctxt->method->name); | ||
1162 | else { | ||
1163 | debug("%s: confirmation mismatch", __func__); | ||
1164 | /* XXX stash this so if auth succeeds then we can warn/kill */ | ||
1165 | } | ||
1166 | |||
1167 | userauth_jpake_cleanup(authctxt); | ||
1168 | } | ||
1169 | #endif /* JPAKE */ | ||
1170 | |||
1171 | static int | 953 | static int |
1172 | identity_sign(Identity *id, u_char **sigp, u_int *lenp, | 954 | identity_sign(Identity *id, u_char **sigp, u_int *lenp, |
1173 | u_char *data, u_int datalen) | 955 | u_char *data, u_int datalen) |
@@ -1344,7 +1126,7 @@ load_identity_file(char *filename, int userprovided) | |||
1344 | debug2("no passphrase given, try next key"); | 1126 | debug2("no passphrase given, try next key"); |
1345 | quit = 1; | 1127 | quit = 1; |
1346 | } | 1128 | } |
1347 | memset(passphrase, 0, strlen(passphrase)); | 1129 | explicit_bzero(passphrase, strlen(passphrase)); |
1348 | free(passphrase); | 1130 | free(passphrase); |
1349 | if (private != NULL || quit) | 1131 | if (private != NULL || quit) |
1350 | break; | 1132 | break; |
@@ -1408,7 +1190,7 @@ pubkey_prepare(Authctxt *authctxt) | |||
1408 | /* If IdentitiesOnly set and key not found then don't use it */ | 1190 | /* If IdentitiesOnly set and key not found then don't use it */ |
1409 | if (!found && options.identities_only) { | 1191 | if (!found && options.identities_only) { |
1410 | TAILQ_REMOVE(&files, id, next); | 1192 | TAILQ_REMOVE(&files, id, next); |
1411 | bzero(id, sizeof(*id)); | 1193 | explicit_bzero(id, sizeof(*id)); |
1412 | free(id); | 1194 | free(id); |
1413 | } | 1195 | } |
1414 | } | 1196 | } |
@@ -1603,7 +1385,7 @@ input_userauth_info_req(int type, u_int32_t seq, void *ctxt) | |||
1603 | response = read_passphrase(prompt, echo ? RP_ECHO : 0); | 1385 | response = read_passphrase(prompt, echo ? RP_ECHO : 0); |
1604 | 1386 | ||
1605 | packet_put_cstring(response); | 1387 | packet_put_cstring(response); |
1606 | memset(response, 0, strlen(response)); | 1388 | explicit_bzero(response, strlen(response)); |
1607 | free(response); | 1389 | free(response); |
1608 | free(prompt); | 1390 | free(prompt); |
1609 | } | 1391 | } |
@@ -1773,7 +1555,7 @@ userauth_hostbased(Authctxt *authctxt) | |||
1773 | packet_put_cstring(chost); | 1555 | packet_put_cstring(chost); |
1774 | packet_put_cstring(authctxt->local_user); | 1556 | packet_put_cstring(authctxt->local_user); |
1775 | packet_put_string(signature, slen); | 1557 | packet_put_string(signature, slen); |
1776 | memset(signature, 's', slen); | 1558 | explicit_bzero(signature, slen); |
1777 | free(signature); | 1559 | free(signature); |
1778 | free(chost); | 1560 | free(chost); |
1779 | free(pkalg); | 1561 | free(pkalg); |
@@ -1783,79 +1565,6 @@ userauth_hostbased(Authctxt *authctxt) | |||
1783 | return 1; | 1565 | return 1; |
1784 | } | 1566 | } |
1785 | 1567 | ||
1786 | #ifdef JPAKE | ||
1787 | int | ||
1788 | userauth_jpake(Authctxt *authctxt) | ||
1789 | { | ||
1790 | struct jpake_ctx *pctx; | ||
1791 | u_char *x1_proof, *x2_proof; | ||
1792 | u_int x1_proof_len, x2_proof_len; | ||
1793 | static int attempt = 0; /* XXX share with userauth_password's? */ | ||
1794 | |||
1795 | if (attempt++ >= options.number_of_password_prompts) | ||
1796 | return 0; | ||
1797 | if (attempt != 1) | ||
1798 | error("Permission denied, please try again."); | ||
1799 | |||
1800 | if (authctxt->methoddata != NULL) | ||
1801 | fatal("%s: authctxt->methoddata already set (%p)", | ||
1802 | __func__, authctxt->methoddata); | ||
1803 | |||
1804 | authctxt->methoddata = pctx = jpake_new(); | ||
1805 | |||
1806 | /* | ||
1807 | * Send request immediately, to get the protocol going while | ||
1808 | * we do the initial computations. | ||
1809 | */ | ||
1810 | packet_start(SSH2_MSG_USERAUTH_REQUEST); | ||
1811 | packet_put_cstring(authctxt->server_user); | ||
1812 | packet_put_cstring(authctxt->service); | ||
1813 | packet_put_cstring(authctxt->method->name); | ||
1814 | packet_send(); | ||
1815 | packet_write_wait(); | ||
1816 | |||
1817 | jpake_step1(pctx->grp, | ||
1818 | &pctx->client_id, &pctx->client_id_len, | ||
1819 | &pctx->x1, &pctx->x2, &pctx->g_x1, &pctx->g_x2, | ||
1820 | &x1_proof, &x1_proof_len, | ||
1821 | &x2_proof, &x2_proof_len); | ||
1822 | |||
1823 | JPAKE_DEBUG_CTX((pctx, "step 1 sending in %s", __func__)); | ||
1824 | |||
1825 | packet_start(SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP1); | ||
1826 | packet_put_string(pctx->client_id, pctx->client_id_len); | ||
1827 | packet_put_bignum2(pctx->g_x1); | ||
1828 | packet_put_bignum2(pctx->g_x2); | ||
1829 | packet_put_string(x1_proof, x1_proof_len); | ||
1830 | packet_put_string(x2_proof, x2_proof_len); | ||
1831 | packet_send(); | ||
1832 | |||
1833 | bzero(x1_proof, x1_proof_len); | ||
1834 | bzero(x2_proof, x2_proof_len); | ||
1835 | free(x1_proof); | ||
1836 | free(x2_proof); | ||
1837 | |||
1838 | /* Expect step 1 packet from peer */ | ||
1839 | dispatch_set(SSH2_MSG_USERAUTH_JPAKE_SERVER_STEP1, | ||
1840 | input_userauth_jpake_server_step1); | ||
1841 | dispatch_set(SSH2_MSG_USERAUTH_SUCCESS, | ||
1842 | &input_userauth_success_unexpected); | ||
1843 | |||
1844 | return 1; | ||
1845 | } | ||
1846 | |||
1847 | void | ||
1848 | userauth_jpake_cleanup(Authctxt *authctxt) | ||
1849 | { | ||
1850 | debug3("%s: clean up", __func__); | ||
1851 | if (authctxt->methoddata != NULL) { | ||
1852 | jpake_free(authctxt->methoddata); | ||
1853 | authctxt->methoddata = NULL; | ||
1854 | } | ||
1855 | dispatch_set(SSH2_MSG_USERAUTH_SUCCESS, &input_userauth_success); | ||
1856 | } | ||
1857 | #endif /* JPAKE */ | ||
1858 | |||
1859 | /* find auth method */ | 1568 | /* find auth method */ |
1860 | 1569 | ||
1861 | /* | 1570 | /* |
@@ -640,4 +640,4 @@ CAVEATS | |||
640 | System security is not improved unless rshd, rlogind, and rexecd are | 640 | System security is not improved unless rshd, rlogind, and rexecd are |
641 | disabled (thus completely disabling rlogin and rsh into the machine). | 641 | disabled (thus completely disabling rlogin and rsh into the machine). |
642 | 642 | ||
643 | OpenBSD 5.4 December 7, 2013 OpenBSD 5.4 | 643 | OpenBSD 5.5 December 7, 2013 OpenBSD 5.5 |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshd.c,v 1.414 2014/01/09 23:26:48 djm Exp $ */ | 1 | /* $OpenBSD: sshd.c,v 1.420 2014/02/26 21:53:37 markus Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -74,7 +74,6 @@ | |||
74 | 74 | ||
75 | #include <openssl/dh.h> | 75 | #include <openssl/dh.h> |
76 | #include <openssl/bn.h> | 76 | #include <openssl/bn.h> |
77 | #include <openssl/md5.h> | ||
78 | #include <openssl/rand.h> | 77 | #include <openssl/rand.h> |
79 | #include "openbsd-compat/openssl-compat.h" | 78 | #include "openbsd-compat/openssl-compat.h" |
80 | 79 | ||
@@ -96,6 +95,7 @@ | |||
96 | #include "uidswap.h" | 95 | #include "uidswap.h" |
97 | #include "compat.h" | 96 | #include "compat.h" |
98 | #include "cipher.h" | 97 | #include "cipher.h" |
98 | #include "digest.h" | ||
99 | #include "key.h" | 99 | #include "key.h" |
100 | #include "kex.h" | 100 | #include "kex.h" |
101 | #include "dh.h" | 101 | #include "dh.h" |
@@ -579,7 +579,7 @@ destroy_sensitive_data(void) | |||
579 | } | 579 | } |
580 | } | 580 | } |
581 | sensitive_data.ssh1_host_key = NULL; | 581 | sensitive_data.ssh1_host_key = NULL; |
582 | memset(sensitive_data.ssh1_cookie, 0, SSH_SESSION_KEY_LENGTH); | 582 | explicit_bzero(sensitive_data.ssh1_cookie, SSH_SESSION_KEY_LENGTH); |
583 | } | 583 | } |
584 | 584 | ||
585 | /* Demote private to public keys for network child */ | 585 | /* Demote private to public keys for network child */ |
@@ -618,10 +618,16 @@ privsep_preauth_child(void) | |||
618 | /* Enable challenge-response authentication for privilege separation */ | 618 | /* Enable challenge-response authentication for privilege separation */ |
619 | privsep_challenge_enable(); | 619 | privsep_challenge_enable(); |
620 | 620 | ||
621 | #ifdef GSSAPI | ||
622 | /* Cache supported mechanism OIDs for later use */ | ||
623 | if (options.gss_authentication) | ||
624 | ssh_gssapi_prepare_supported_oids(); | ||
625 | #endif | ||
626 | |||
621 | arc4random_stir(); | 627 | arc4random_stir(); |
622 | arc4random_buf(rnd, sizeof(rnd)); | 628 | arc4random_buf(rnd, sizeof(rnd)); |
623 | RAND_seed(rnd, sizeof(rnd)); | 629 | RAND_seed(rnd, sizeof(rnd)); |
624 | bzero(rnd, sizeof(rnd)); | 630 | explicit_bzero(rnd, sizeof(rnd)); |
625 | 631 | ||
626 | /* Demote the private keys to public keys. */ | 632 | /* Demote the private keys to public keys. */ |
627 | demote_sensitive_data(); | 633 | demote_sensitive_data(); |
@@ -756,7 +762,7 @@ privsep_postauth(Authctxt *authctxt) | |||
756 | arc4random_stir(); | 762 | arc4random_stir(); |
757 | arc4random_buf(rnd, sizeof(rnd)); | 763 | arc4random_buf(rnd, sizeof(rnd)); |
758 | RAND_seed(rnd, sizeof(rnd)); | 764 | RAND_seed(rnd, sizeof(rnd)); |
759 | bzero(rnd, sizeof(rnd)); | 765 | explicit_bzero(rnd, sizeof(rnd)); |
760 | 766 | ||
761 | /* Drop privileges */ | 767 | /* Drop privileges */ |
762 | do_setusercontext(authctxt->pw); | 768 | do_setusercontext(authctxt->pw); |
@@ -1355,7 +1361,7 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s) | |||
1355 | arc4random_stir(); | 1361 | arc4random_stir(); |
1356 | arc4random_buf(rnd, sizeof(rnd)); | 1362 | arc4random_buf(rnd, sizeof(rnd)); |
1357 | RAND_seed(rnd, sizeof(rnd)); | 1363 | RAND_seed(rnd, sizeof(rnd)); |
1358 | bzero(rnd, sizeof(rnd)); | 1364 | explicit_bzero(rnd, sizeof(rnd)); |
1359 | } | 1365 | } |
1360 | 1366 | ||
1361 | /* child process check (or debug mode) */ | 1367 | /* child process check (or debug mode) */ |
@@ -1657,7 +1663,8 @@ main(int ac, char **av) | |||
1657 | fatal("Privilege separation user %s does not exist", | 1663 | fatal("Privilege separation user %s does not exist", |
1658 | SSH_PRIVSEP_USER); | 1664 | SSH_PRIVSEP_USER); |
1659 | } else { | 1665 | } else { |
1660 | memset(privsep_pw->pw_passwd, 0, strlen(privsep_pw->pw_passwd)); | 1666 | explicit_bzero(privsep_pw->pw_passwd, |
1667 | strlen(privsep_pw->pw_passwd)); | ||
1661 | privsep_pw = pwcopy(privsep_pw); | 1668 | privsep_pw = pwcopy(privsep_pw); |
1662 | free(privsep_pw->pw_passwd); | 1669 | free(privsep_pw->pw_passwd); |
1663 | privsep_pw->pw_passwd = xstrdup("*"); | 1670 | privsep_pw->pw_passwd = xstrdup("*"); |
@@ -2341,7 +2348,7 @@ do_ssh1_kex(void) | |||
2341 | get_remote_ipaddr(), len, (u_long)sizeof(session_key)); | 2348 | get_remote_ipaddr(), len, (u_long)sizeof(session_key)); |
2342 | rsafail++; | 2349 | rsafail++; |
2343 | } else { | 2350 | } else { |
2344 | memset(session_key, 0, sizeof(session_key)); | 2351 | explicit_bzero(session_key, sizeof(session_key)); |
2345 | BN_bn2bin(session_key_int, | 2352 | BN_bn2bin(session_key_int, |
2346 | session_key + sizeof(session_key) - len); | 2353 | session_key + sizeof(session_key) - len); |
2347 | 2354 | ||
@@ -2360,20 +2367,26 @@ do_ssh1_kex(void) | |||
2360 | if (rsafail) { | 2367 | if (rsafail) { |
2361 | int bytes = BN_num_bytes(session_key_int); | 2368 | int bytes = BN_num_bytes(session_key_int); |
2362 | u_char *buf = xmalloc(bytes); | 2369 | u_char *buf = xmalloc(bytes); |
2363 | MD5_CTX md; | 2370 | struct ssh_digest_ctx *md; |
2364 | 2371 | ||
2365 | logit("do_connection: generating a fake encryption key"); | 2372 | logit("do_connection: generating a fake encryption key"); |
2366 | BN_bn2bin(session_key_int, buf); | 2373 | BN_bn2bin(session_key_int, buf); |
2367 | MD5_Init(&md); | 2374 | if ((md = ssh_digest_start(SSH_DIGEST_MD5)) == NULL || |
2368 | MD5_Update(&md, buf, bytes); | 2375 | ssh_digest_update(md, buf, bytes) < 0 || |
2369 | MD5_Update(&md, sensitive_data.ssh1_cookie, SSH_SESSION_KEY_LENGTH); | 2376 | ssh_digest_update(md, sensitive_data.ssh1_cookie, |
2370 | MD5_Final(session_key, &md); | 2377 | SSH_SESSION_KEY_LENGTH) < 0 || |
2371 | MD5_Init(&md); | 2378 | ssh_digest_final(md, session_key, sizeof(session_key)) < 0) |
2372 | MD5_Update(&md, session_key, 16); | 2379 | fatal("%s: md5 failed", __func__); |
2373 | MD5_Update(&md, buf, bytes); | 2380 | ssh_digest_free(md); |
2374 | MD5_Update(&md, sensitive_data.ssh1_cookie, SSH_SESSION_KEY_LENGTH); | 2381 | if ((md = ssh_digest_start(SSH_DIGEST_MD5)) == NULL || |
2375 | MD5_Final(session_key + 16, &md); | 2382 | ssh_digest_update(md, session_key, 16) < 0 || |
2376 | memset(buf, 0, bytes); | 2383 | ssh_digest_update(md, sensitive_data.ssh1_cookie, |
2384 | SSH_SESSION_KEY_LENGTH) < 0 || | ||
2385 | ssh_digest_final(md, session_key + 16, | ||
2386 | sizeof(session_key) - 16) < 0) | ||
2387 | fatal("%s: md5 failed", __func__); | ||
2388 | ssh_digest_free(md); | ||
2389 | explicit_bzero(buf, bytes); | ||
2377 | free(buf); | 2390 | free(buf); |
2378 | for (i = 0; i < 16; i++) | 2391 | for (i = 0; i < 16; i++) |
2379 | session_id[i] = session_key[i] ^ session_key[i + 16]; | 2392 | session_id[i] = session_key[i] ^ session_key[i + 16]; |
@@ -2391,7 +2404,7 @@ do_ssh1_kex(void) | |||
2391 | packet_set_encryption_key(session_key, SSH_SESSION_KEY_LENGTH, cipher_type); | 2404 | packet_set_encryption_key(session_key, SSH_SESSION_KEY_LENGTH, cipher_type); |
2392 | 2405 | ||
2393 | /* Destroy our copy of the session key. It is no longer needed. */ | 2406 | /* Destroy our copy of the session key. It is no longer needed. */ |
2394 | memset(session_key, 0, sizeof(session_key)); | 2407 | explicit_bzero(session_key, sizeof(session_key)); |
2395 | 2408 | ||
2396 | debug("Received session key; encryption turned on."); | 2409 | debug("Received session key; encryption turned on."); |
2397 | 2410 | ||
diff --git a/sshd_config.0 b/sshd_config.0 index 5962b02b9..413c26008 100644 --- a/sshd_config.0 +++ b/sshd_config.0 | |||
@@ -374,6 +374,12 @@ DESCRIPTION | |||
374 | interactive sessions and ``throughput'' for non-interactive | 374 | interactive sessions and ``throughput'' for non-interactive |
375 | sessions. | 375 | sessions. |
376 | 376 | ||
377 | KbdInteractiveAuthentication | ||
378 | Specifies whether to allow keyboard-interactive authentication. | ||
379 | The argument to this keyword must be ``yes'' or ``no''. The | ||
380 | default is to use whatever value ChallengeResponseAuthentication | ||
381 | is set to (by default ``yes''). | ||
382 | |||
377 | KerberosAuthentication | 383 | KerberosAuthentication |
378 | Specifies whether the password provided by the user for | 384 | Specifies whether the password provided by the user for |
379 | PasswordAuthentication will be validated through the Kerberos | 385 | PasswordAuthentication will be validated through the Kerberos |
@@ -460,7 +466,9 @@ DESCRIPTION | |||
460 | Match Introduces a conditional block. If all of the criteria on the | 466 | Match Introduces a conditional block. If all of the criteria on the |
461 | Match line are satisfied, the keywords on the following lines | 467 | Match line are satisfied, the keywords on the following lines |
462 | override those set in the global section of the config file, | 468 | override those set in the global section of the config file, |
463 | until either another Match line or the end of the file. | 469 | until either another Match line or the end of the file. If a |
470 | keyword appears in multiple Match blocks that are satisified, | ||
471 | only the first instance of the keyword is applied. | ||
464 | 472 | ||
465 | The arguments to Match are one or more criteria-pattern pairs or | 473 | The arguments to Match are one or more criteria-pattern pairs or |
466 | the single token All which matches all criteria. The available | 474 | the single token All which matches all criteria. The available |
@@ -824,4 +832,4 @@ AUTHORS | |||
824 | versions 1.5 and 2.0. Niels Provos and Markus Friedl contributed support | 832 | versions 1.5 and 2.0. Niels Provos and Markus Friedl contributed support |
825 | for privilege separation. | 833 | for privilege separation. |
826 | 834 | ||
827 | OpenBSD 5.4 December 8, 2013 OpenBSD 5.4 | 835 | OpenBSD 5.5 February 27, 2014 OpenBSD 5.5 |
diff --git a/sshd_config.5 b/sshd_config.5 index 3b21ea6e7..ce71efe3c 100644 --- a/sshd_config.5 +++ b/sshd_config.5 | |||
@@ -33,8 +33,8 @@ | |||
33 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 33 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
34 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 34 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
35 | .\" | 35 | .\" |
36 | .\" $OpenBSD: sshd_config.5,v 1.170 2013/12/08 09:53:27 dtucker Exp $ | 36 | .\" $OpenBSD: sshd_config.5,v 1.172 2014/02/27 22:47:07 djm Exp $ |
37 | .Dd $Mdocdate: December 8 2013 $ | 37 | .Dd $Mdocdate: February 27 2014 $ |
38 | .Dt SSHD_CONFIG 5 | 38 | .Dt SSHD_CONFIG 5 |
39 | .Os | 39 | .Os |
40 | .Sh NAME | 40 | .Sh NAME |
@@ -633,6 +633,17 @@ The default is | |||
633 | for interactive sessions and | 633 | for interactive sessions and |
634 | .Dq throughput | 634 | .Dq throughput |
635 | for non-interactive sessions. | 635 | for non-interactive sessions. |
636 | .It Cm KbdInteractiveAuthentication | ||
637 | Specifies whether to allow keyboard-interactive authentication. | ||
638 | The argument to this keyword must be | ||
639 | .Dq yes | ||
640 | or | ||
641 | .Dq no . | ||
642 | The default is to use whatever value | ||
643 | .Cm ChallengeResponseAuthentication | ||
644 | is set to | ||
645 | (by default | ||
646 | .Dq yes ) . | ||
636 | .It Cm KerberosAuthentication | 647 | .It Cm KerberosAuthentication |
637 | Specifies whether the password provided by the user for | 648 | Specifies whether the password provided by the user for |
638 | .Cm PasswordAuthentication | 649 | .Cm PasswordAuthentication |
@@ -759,6 +770,10 @@ line are satisfied, the keywords on the following lines override those | |||
759 | set in the global section of the config file, until either another | 770 | set in the global section of the config file, until either another |
760 | .Cm Match | 771 | .Cm Match |
761 | line or the end of the file. | 772 | line or the end of the file. |
773 | If a keyword appears in multiple | ||
774 | .Cm Match | ||
775 | blocks that are satisified, only the first instance of the keyword is | ||
776 | applied. | ||
762 | .Pp | 777 | .Pp |
763 | The arguments to | 778 | The arguments to |
764 | .Cm Match | 779 | .Cm Match |
diff --git a/sshlogin.c b/sshlogin.c index 2688d8d7b..e79ca9b47 100644 --- a/sshlogin.c +++ b/sshlogin.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshlogin.c,v 1.27 2011/01/11 06:06:09 djm Exp $ */ | 1 | /* $OpenBSD: sshlogin.c,v 1.28 2014/01/31 16:39:19 tedu Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -1,6 +1,6 @@ | |||
1 | /* $OpenBSD: version.h,v 1.69 2014/01/16 07:32:00 djm Exp $ */ | 1 | /* $OpenBSD: version.h,v 1.70 2014/02/27 22:57:40 djm Exp $ */ |
2 | 2 | ||
3 | #define SSH_VERSION "OpenSSH_6.5" | 3 | #define SSH_VERSION "OpenSSH_6.6" |
4 | 4 | ||
5 | #define SSH_PORTABLE "p1" | 5 | #define SSH_PORTABLE "p1" |
6 | #define SSH_RELEASE SSH_VERSION SSH_PORTABLE | 6 | #define SSH_RELEASE SSH_VERSION SSH_PORTABLE |