summaryrefslogtreecommitdiff
path: root/sshbuf-getput-crypto.c
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2014-10-07 13:33:15 +0100
committerColin Watson <cjwatson@debian.org>2014-10-07 14:27:30 +0100
commitf0b009aea83e9ff3a50be30f51012099a5143c16 (patch)
tree3825e6f7e3b7ea4481d06ed89aba9a7a95150df5 /sshbuf-getput-crypto.c
parent47f0bad4330b16ec3bad870fcf9839c196e42c12 (diff)
parent762c062828f5a8f6ed189ed6e44ad38fd92f8b36 (diff)
Merge 6.7p1.
* New upstream release (http://www.openssh.com/txt/release-6.7): - sshd(8): The default set of ciphers and MACs has been altered to remove unsafe algorithms. In particular, CBC ciphers and arcfour* are disabled by default. The full set of algorithms remains available if configured explicitly via the Ciphers and MACs sshd_config options. - ssh(1), sshd(8): Add support for Unix domain socket forwarding. A remote TCP port may be forwarded to a local Unix domain socket and vice versa or both ends may be a Unix domain socket (closes: #236718). - ssh(1), ssh-keygen(1): Add support for SSHFP DNS records for ED25519 key types. - sftp(1): Allow resumption of interrupted uploads. - ssh(1): When rekeying, skip file/DNS lookups of the hostkey if it is the same as the one sent during initial key exchange. - sshd(8): Allow explicit ::1 and 127.0.0.1 forwarding bind addresses when GatewayPorts=no; allows client to choose address family. - sshd(8): Add a sshd_config PermitUserRC option to control whether ~/.ssh/rc is executed, mirroring the no-user-rc authorized_keys option. - ssh(1): Add a %C escape sequence for LocalCommand and ControlPath that expands to a unique identifer based on a hash of the tuple of (local host, remote user, hostname, port). Helps avoid exceeding miserly pathname limits for Unix domain sockets in multiplexing control paths. - sshd(8): Make the "Too many authentication failures" message include the user, source address, port and protocol in a format similar to the authentication success / failure messages. - Use CLOCK_BOOTTIME in preference to CLOCK_MONOTONIC when it is available. It considers time spent suspended, thereby ensuring timeouts (e.g. for expiring agent keys) fire correctly (closes: #734553). - Use prctl() to prevent sftp-server from accessing /proc/self/{mem,maps}. * Restore TCP wrappers support, removed upstream in 6.7. It is true that dropping this reduces preauth attack surface in sshd. On the other hand, this support seems to be quite widely used, and abruptly dropping it (from the perspective of users who don't read openssh-unix-dev) could easily cause more serious problems in practice. It's not entirely clear what the right long-term answer for Debian is, but it at least probably doesn't involve dropping this feature shortly before a freeze. * Replace patch to disable OpenSSL version check with an updated version of Kurt Roeckx's patch from #732940 to just avoid checking the status field.
Diffstat (limited to 'sshbuf-getput-crypto.c')
-rw-r--r--sshbuf-getput-crypto.c237
1 files changed, 237 insertions, 0 deletions
diff --git a/sshbuf-getput-crypto.c b/sshbuf-getput-crypto.c
new file mode 100644
index 000000000..74351d3e5
--- /dev/null
+++ b/sshbuf-getput-crypto.c
@@ -0,0 +1,237 @@
1/* $OpenBSD: sshbuf-getput-crypto.c,v 1.2 2014/06/18 15:42:09 naddy Exp $ */
2/*
3 * Copyright (c) 2011 Damien Miller
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#define SSHBUF_INTERNAL
19#include "includes.h"
20
21#include <sys/types.h>
22#include <stdlib.h>
23#include <stdio.h>
24#include <string.h>
25
26#include <openssl/bn.h>
27#ifdef OPENSSL_HAS_ECC
28# include <openssl/ec.h>
29#endif /* OPENSSL_HAS_ECC */
30
31#include "ssherr.h"
32#include "sshbuf.h"
33
34int
35sshbuf_get_bignum2(struct sshbuf *buf, BIGNUM *v)
36{
37 const u_char *d;
38 size_t len;
39 int r;
40
41 if ((r = sshbuf_peek_string_direct(buf, &d, &len)) < 0)
42 return r;
43 /* Refuse negative (MSB set) bignums */
44 if ((len != 0 && (*d & 0x80) != 0))
45 return SSH_ERR_BIGNUM_IS_NEGATIVE;
46 /* Refuse overlong bignums, allow prepended \0 to avoid MSB set */
47 if (len > SSHBUF_MAX_BIGNUM + 1 ||
48 (len == SSHBUF_MAX_BIGNUM + 1 && *d != 0))
49 return SSH_ERR_BIGNUM_TOO_LARGE;
50 if (v != NULL && BN_bin2bn(d, len, v) == NULL)
51 return SSH_ERR_ALLOC_FAIL;
52 /* Consume the string */
53 if (sshbuf_get_string_direct(buf, NULL, NULL) != 0) {
54 /* Shouldn't happen */
55 SSHBUF_DBG(("SSH_ERR_INTERNAL_ERROR"));
56 SSHBUF_ABORT();
57 return SSH_ERR_INTERNAL_ERROR;
58 }
59 return 0;
60}
61
62int
63sshbuf_get_bignum1(struct sshbuf *buf, BIGNUM *v)
64{
65 const u_char *d = sshbuf_ptr(buf);
66 u_int16_t len_bits;
67 size_t len_bytes;
68
69 /* Length in bits */
70 if (sshbuf_len(buf) < 2)
71 return SSH_ERR_MESSAGE_INCOMPLETE;
72 len_bits = PEEK_U16(d);
73 len_bytes = (len_bits + 7) >> 3;
74 if (len_bytes > SSHBUF_MAX_BIGNUM)
75 return SSH_ERR_BIGNUM_TOO_LARGE;
76 if (sshbuf_len(buf) < 2 + len_bytes)
77 return SSH_ERR_MESSAGE_INCOMPLETE;
78 if (v != NULL && BN_bin2bn(d + 2, len_bytes, v) == NULL)
79 return SSH_ERR_ALLOC_FAIL;
80 if (sshbuf_consume(buf, 2 + len_bytes) != 0) {
81 SSHBUF_DBG(("SSH_ERR_INTERNAL_ERROR"));
82 SSHBUF_ABORT();
83 return SSH_ERR_INTERNAL_ERROR;
84 }
85 return 0;
86}
87
88#ifdef OPENSSL_HAS_ECC
89static int
90get_ec(const u_char *d, size_t len, EC_POINT *v, const EC_GROUP *g)
91{
92 /* Refuse overlong bignums */
93 if (len == 0 || len > SSHBUF_MAX_ECPOINT)
94 return SSH_ERR_ECPOINT_TOO_LARGE;
95 /* Only handle uncompressed points */
96 if (*d != POINT_CONVERSION_UNCOMPRESSED)
97 return SSH_ERR_INVALID_FORMAT;
98 if (v != NULL && EC_POINT_oct2point(g, v, d, len, NULL) != 1)
99 return SSH_ERR_INVALID_FORMAT; /* XXX assumption */
100 return 0;
101}
102
103int
104sshbuf_get_ec(struct sshbuf *buf, EC_POINT *v, const EC_GROUP *g)
105{
106 const u_char *d;
107 size_t len;
108 int r;
109
110 if ((r = sshbuf_peek_string_direct(buf, &d, &len)) < 0)
111 return r;
112 if ((r = get_ec(d, len, v, g)) != 0)
113 return r;
114 /* Skip string */
115 if (sshbuf_get_string_direct(buf, NULL, NULL) != 0) {
116 /* Shouldn't happen */
117 SSHBUF_DBG(("SSH_ERR_INTERNAL_ERROR"));
118 SSHBUF_ABORT();
119 return SSH_ERR_INTERNAL_ERROR;
120 }
121 return 0;
122}
123
124int
125sshbuf_get_eckey(struct sshbuf *buf, EC_KEY *v)
126{
127 EC_POINT *pt = EC_POINT_new(EC_KEY_get0_group(v));
128 int r;
129 const u_char *d;
130 size_t len;
131
132 if (pt == NULL) {
133 SSHBUF_DBG(("SSH_ERR_ALLOC_FAIL"));
134 return SSH_ERR_ALLOC_FAIL;
135 }
136 if ((r = sshbuf_peek_string_direct(buf, &d, &len)) < 0) {
137 EC_POINT_free(pt);
138 return r;
139 }
140 if ((r = get_ec(d, len, pt, EC_KEY_get0_group(v))) != 0) {
141 EC_POINT_free(pt);
142 return r;
143 }
144 if (EC_KEY_set_public_key(v, pt) != 1) {
145 EC_POINT_free(pt);
146 return SSH_ERR_ALLOC_FAIL; /* XXX assumption */
147 }
148 EC_POINT_free(pt);
149 /* Skip string */
150 if (sshbuf_get_string_direct(buf, NULL, NULL) != 0) {
151 /* Shouldn't happen */
152 SSHBUF_DBG(("SSH_ERR_INTERNAL_ERROR"));
153 SSHBUF_ABORT();
154 return SSH_ERR_INTERNAL_ERROR;
155 }
156 return 0;
157}
158#endif /* OPENSSL_HAS_ECC */
159
160int
161sshbuf_put_bignum2(struct sshbuf *buf, const BIGNUM *v)
162{
163 u_char d[SSHBUF_MAX_BIGNUM + 1];
164 int len = BN_num_bytes(v), prepend = 0, r;
165
166 if (len < 0 || len > SSHBUF_MAX_BIGNUM)
167 return SSH_ERR_INVALID_ARGUMENT;
168 *d = '\0';
169 if (BN_bn2bin(v, d + 1) != len)
170 return SSH_ERR_INTERNAL_ERROR; /* Shouldn't happen */
171 /* If MSB is set, prepend a \0 */
172 if (len > 0 && (d[1] & 0x80) != 0)
173 prepend = 1;
174 if ((r = sshbuf_put_string(buf, d + 1 - prepend, len + prepend)) < 0) {
175 bzero(d, sizeof(d));
176 return r;
177 }
178 bzero(d, sizeof(d));
179 return 0;
180}
181
182int
183sshbuf_put_bignum1(struct sshbuf *buf, const BIGNUM *v)
184{
185 int r, len_bits = BN_num_bits(v);
186 size_t len_bytes = (len_bits + 7) / 8;
187 u_char d[SSHBUF_MAX_BIGNUM], *dp;
188
189 if (len_bits < 0 || len_bytes > SSHBUF_MAX_BIGNUM)
190 return SSH_ERR_INVALID_ARGUMENT;
191 if (BN_bn2bin(v, d) != (int)len_bytes)
192 return SSH_ERR_INTERNAL_ERROR; /* Shouldn't happen */
193 if ((r = sshbuf_reserve(buf, len_bytes + 2, &dp)) < 0) {
194 bzero(d, sizeof(d));
195 return r;
196 }
197 POKE_U16(dp, len_bits);
198 memcpy(dp + 2, d, len_bytes);
199 bzero(d, sizeof(d));
200 return 0;
201}
202
203#ifdef OPENSSL_HAS_ECC
204int
205sshbuf_put_ec(struct sshbuf *buf, const EC_POINT *v, const EC_GROUP *g)
206{
207 u_char d[SSHBUF_MAX_ECPOINT];
208 BN_CTX *bn_ctx;
209 size_t len;
210 int ret;
211
212 if ((bn_ctx = BN_CTX_new()) == NULL)
213 return SSH_ERR_ALLOC_FAIL;
214 if ((len = EC_POINT_point2oct(g, v, POINT_CONVERSION_UNCOMPRESSED,
215 NULL, 0, bn_ctx)) > SSHBUF_MAX_ECPOINT) {
216 BN_CTX_free(bn_ctx);
217 return SSH_ERR_INVALID_ARGUMENT;
218 }
219 if (EC_POINT_point2oct(g, v, POINT_CONVERSION_UNCOMPRESSED,
220 d, len, bn_ctx) != len) {
221 BN_CTX_free(bn_ctx);
222 return SSH_ERR_INTERNAL_ERROR; /* Shouldn't happen */
223 }
224 BN_CTX_free(bn_ctx);
225 ret = sshbuf_put_string(buf, d, len);
226 bzero(d, len);
227 return ret;
228}
229
230int
231sshbuf_put_eckey(struct sshbuf *buf, const EC_KEY *v)
232{
233 return sshbuf_put_ec(buf, EC_KEY_get0_public_key(v),
234 EC_KEY_get0_group(v));
235}
236#endif /* OPENSSL_HAS_ECC */
237