diff options
author | Colin Watson <cjwatson@debian.org> | 2014-10-07 13:33:15 +0100 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2014-10-07 14:27:30 +0100 |
commit | f0b009aea83e9ff3a50be30f51012099a5143c16 (patch) | |
tree | 3825e6f7e3b7ea4481d06ed89aba9a7a95150df5 /key.c | |
parent | 47f0bad4330b16ec3bad870fcf9839c196e42c12 (diff) | |
parent | 762c062828f5a8f6ed189ed6e44ad38fd92f8b36 (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 'key.c')
-rw-r--r-- | key.c | 2751 |
1 files changed, 302 insertions, 2449 deletions
@@ -1,2090 +1,242 @@ | |||
1 | /* $OpenBSD: key.c,v 1.116 2014/02/02 03:44:31 djm Exp $ */ | 1 | /* $OpenBSD: key.c,v 1.122 2014/07/22 01:18:50 dtucker Exp $ */ |
2 | /* | 2 | /* |
3 | * read_bignum(): | 3 | * placed in the public domain |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | ||
5 | * | ||
6 | * As far as I am concerned, the code I have written for this software | ||
7 | * can be used freely for any purpose. Any derived versions of this | ||
8 | * software must be clearly marked as such, and if the derived work is | ||
9 | * incompatible with the protocol description in the RFC file, it must be | ||
10 | * called by a name other than "ssh" or "Secure Shell". | ||
11 | * | ||
12 | * | ||
13 | * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. | ||
14 | * Copyright (c) 2008 Alexander von Gernler. All rights reserved. | ||
15 | * | ||
16 | * Redistribution and use in source and binary forms, with or without | ||
17 | * modification, are permitted provided that the following conditions | ||
18 | * are met: | ||
19 | * 1. Redistributions of source code must retain the above copyright | ||
20 | * notice, this list of conditions and the following disclaimer. | ||
21 | * 2. Redistributions in binary form must reproduce the above copyright | ||
22 | * notice, this list of conditions and the following disclaimer in the | ||
23 | * documentation and/or other materials provided with the distribution. | ||
24 | * | ||
25 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | ||
26 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||
27 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||
28 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
29 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
30 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
31 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
32 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
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. | ||
35 | */ | 4 | */ |
36 | 5 | ||
37 | #include "includes.h" | 6 | #include "includes.h" |
38 | 7 | ||
39 | #include <sys/param.h> | 8 | #include <sys/param.h> |
40 | #include <sys/types.h> | 9 | #include <sys/types.h> |
41 | 10 | #include <errno.h> | |
42 | #include "crypto_api.h" | ||
43 | |||
44 | #include <openssl/evp.h> | ||
45 | #include <openbsd-compat/openssl-compat.h> | ||
46 | |||
47 | #include <stdarg.h> | 11 | #include <stdarg.h> |
48 | #include <stdio.h> | 12 | #include <stdio.h> |
49 | #include <string.h> | ||
50 | 13 | ||
51 | #include "xmalloc.h" | 14 | #define SSH_KEY_NO_DEFINE |
52 | #include "key.h" | 15 | #include "key.h" |
53 | #include "rsa.h" | ||
54 | #include "uuencode.h" | ||
55 | #include "buffer.h" | ||
56 | #include "log.h" | ||
57 | #include "misc.h" | ||
58 | #include "ssh2.h" | ||
59 | #include "digest.h" | ||
60 | |||
61 | static int to_blob(const Key *, u_char **, u_int *, int); | ||
62 | static Key *key_from_blob2(const u_char *, u_int, int); | ||
63 | |||
64 | static struct KeyCert * | ||
65 | cert_new(void) | ||
66 | { | ||
67 | struct KeyCert *cert; | ||
68 | |||
69 | cert = xcalloc(1, sizeof(*cert)); | ||
70 | buffer_init(&cert->certblob); | ||
71 | buffer_init(&cert->critical); | ||
72 | buffer_init(&cert->extensions); | ||
73 | cert->key_id = NULL; | ||
74 | cert->principals = NULL; | ||
75 | cert->signature_key = NULL; | ||
76 | return cert; | ||
77 | } | ||
78 | |||
79 | Key * | ||
80 | key_new(int type) | ||
81 | { | ||
82 | Key *k; | ||
83 | RSA *rsa; | ||
84 | DSA *dsa; | ||
85 | k = xcalloc(1, sizeof(*k)); | ||
86 | k->type = type; | ||
87 | k->ecdsa = NULL; | ||
88 | k->ecdsa_nid = -1; | ||
89 | k->dsa = NULL; | ||
90 | k->rsa = NULL; | ||
91 | k->cert = NULL; | ||
92 | k->ed25519_sk = NULL; | ||
93 | k->ed25519_pk = NULL; | ||
94 | switch (k->type) { | ||
95 | case KEY_RSA1: | ||
96 | case KEY_RSA: | ||
97 | case KEY_RSA_CERT_V00: | ||
98 | case KEY_RSA_CERT: | ||
99 | if ((rsa = RSA_new()) == NULL) | ||
100 | fatal("key_new: RSA_new failed"); | ||
101 | if ((rsa->n = BN_new()) == NULL) | ||
102 | fatal("key_new: BN_new failed"); | ||
103 | if ((rsa->e = BN_new()) == NULL) | ||
104 | fatal("key_new: BN_new failed"); | ||
105 | k->rsa = rsa; | ||
106 | break; | ||
107 | case KEY_DSA: | ||
108 | case KEY_DSA_CERT_V00: | ||
109 | case KEY_DSA_CERT: | ||
110 | if ((dsa = DSA_new()) == NULL) | ||
111 | fatal("key_new: DSA_new failed"); | ||
112 | if ((dsa->p = BN_new()) == NULL) | ||
113 | fatal("key_new: BN_new failed"); | ||
114 | if ((dsa->q = BN_new()) == NULL) | ||
115 | fatal("key_new: BN_new failed"); | ||
116 | if ((dsa->g = BN_new()) == NULL) | ||
117 | fatal("key_new: BN_new failed"); | ||
118 | if ((dsa->pub_key = BN_new()) == NULL) | ||
119 | fatal("key_new: BN_new failed"); | ||
120 | k->dsa = dsa; | ||
121 | break; | ||
122 | #ifdef OPENSSL_HAS_ECC | ||
123 | case KEY_ECDSA: | ||
124 | case KEY_ECDSA_CERT: | ||
125 | /* Cannot do anything until we know the group */ | ||
126 | break; | ||
127 | #endif | ||
128 | case KEY_ED25519: | ||
129 | case KEY_ED25519_CERT: | ||
130 | /* no need to prealloc */ | ||
131 | break; | ||
132 | case KEY_UNSPEC: | ||
133 | break; | ||
134 | default: | ||
135 | fatal("key_new: bad key type %d", k->type); | ||
136 | break; | ||
137 | } | ||
138 | 16 | ||
139 | if (key_is_cert(k)) | 17 | #include "compat.h" |
140 | k->cert = cert_new(); | 18 | #include "sshkey.h" |
141 | 19 | #include "ssherr.h" | |
142 | return k; | 20 | #include "log.h" |
143 | } | 21 | #include "authfile.h" |
144 | 22 | ||
145 | void | 23 | void |
146 | key_add_private(Key *k) | 24 | key_add_private(Key *k) |
147 | { | 25 | { |
148 | switch (k->type) { | 26 | int r; |
149 | case KEY_RSA1: | 27 | |
150 | case KEY_RSA: | 28 | if ((r = sshkey_add_private(k)) != 0) |
151 | case KEY_RSA_CERT_V00: | 29 | fatal("%s: %s", __func__, ssh_err(r)); |
152 | case KEY_RSA_CERT: | ||
153 | if ((k->rsa->d = BN_new()) == NULL) | ||
154 | fatal("key_new_private: BN_new failed"); | ||
155 | if ((k->rsa->iqmp = BN_new()) == NULL) | ||
156 | fatal("key_new_private: BN_new failed"); | ||
157 | if ((k->rsa->q = BN_new()) == NULL) | ||
158 | fatal("key_new_private: BN_new failed"); | ||
159 | if ((k->rsa->p = BN_new()) == NULL) | ||
160 | fatal("key_new_private: BN_new failed"); | ||
161 | if ((k->rsa->dmq1 = BN_new()) == NULL) | ||
162 | fatal("key_new_private: BN_new failed"); | ||
163 | if ((k->rsa->dmp1 = BN_new()) == NULL) | ||
164 | fatal("key_new_private: BN_new failed"); | ||
165 | break; | ||
166 | case KEY_DSA: | ||
167 | case KEY_DSA_CERT_V00: | ||
168 | case KEY_DSA_CERT: | ||
169 | if ((k->dsa->priv_key = BN_new()) == NULL) | ||
170 | fatal("key_new_private: BN_new failed"); | ||
171 | break; | ||
172 | case KEY_ECDSA: | ||
173 | case KEY_ECDSA_CERT: | ||
174 | /* Cannot do anything until we know the group */ | ||
175 | break; | ||
176 | case KEY_ED25519: | ||
177 | case KEY_ED25519_CERT: | ||
178 | /* no need to prealloc */ | ||
179 | break; | ||
180 | case KEY_UNSPEC: | ||
181 | break; | ||
182 | default: | ||
183 | break; | ||
184 | } | ||
185 | } | 30 | } |
186 | 31 | ||
187 | Key * | 32 | Key * |
188 | key_new_private(int type) | 33 | key_new_private(int type) |
189 | { | 34 | { |
190 | Key *k = key_new(type); | 35 | Key *ret = NULL; |
191 | |||
192 | key_add_private(k); | ||
193 | return k; | ||
194 | } | ||
195 | |||
196 | static void | ||
197 | cert_free(struct KeyCert *cert) | ||
198 | { | ||
199 | u_int i; | ||
200 | |||
201 | buffer_free(&cert->certblob); | ||
202 | buffer_free(&cert->critical); | ||
203 | buffer_free(&cert->extensions); | ||
204 | free(cert->key_id); | ||
205 | for (i = 0; i < cert->nprincipals; i++) | ||
206 | free(cert->principals[i]); | ||
207 | free(cert->principals); | ||
208 | if (cert->signature_key != NULL) | ||
209 | key_free(cert->signature_key); | ||
210 | free(cert); | ||
211 | } | ||
212 | |||
213 | void | ||
214 | key_free(Key *k) | ||
215 | { | ||
216 | if (k == NULL) | ||
217 | fatal("key_free: key is NULL"); | ||
218 | switch (k->type) { | ||
219 | case KEY_RSA1: | ||
220 | case KEY_RSA: | ||
221 | case KEY_RSA_CERT_V00: | ||
222 | case KEY_RSA_CERT: | ||
223 | if (k->rsa != NULL) | ||
224 | RSA_free(k->rsa); | ||
225 | k->rsa = NULL; | ||
226 | break; | ||
227 | case KEY_DSA: | ||
228 | case KEY_DSA_CERT_V00: | ||
229 | case KEY_DSA_CERT: | ||
230 | if (k->dsa != NULL) | ||
231 | DSA_free(k->dsa); | ||
232 | k->dsa = NULL; | ||
233 | break; | ||
234 | #ifdef OPENSSL_HAS_ECC | ||
235 | case KEY_ECDSA: | ||
236 | case KEY_ECDSA_CERT: | ||
237 | if (k->ecdsa != NULL) | ||
238 | EC_KEY_free(k->ecdsa); | ||
239 | k->ecdsa = NULL; | ||
240 | break; | ||
241 | #endif | ||
242 | case KEY_ED25519: | ||
243 | case KEY_ED25519_CERT: | ||
244 | if (k->ed25519_pk) { | ||
245 | explicit_bzero(k->ed25519_pk, ED25519_PK_SZ); | ||
246 | free(k->ed25519_pk); | ||
247 | k->ed25519_pk = NULL; | ||
248 | } | ||
249 | if (k->ed25519_sk) { | ||
250 | explicit_bzero(k->ed25519_sk, ED25519_SK_SZ); | ||
251 | free(k->ed25519_sk); | ||
252 | k->ed25519_sk = NULL; | ||
253 | } | ||
254 | break; | ||
255 | case KEY_UNSPEC: | ||
256 | break; | ||
257 | default: | ||
258 | fatal("key_free: bad key type %d", k->type); | ||
259 | break; | ||
260 | } | ||
261 | if (key_is_cert(k)) { | ||
262 | if (k->cert != NULL) | ||
263 | cert_free(k->cert); | ||
264 | k->cert = NULL; | ||
265 | } | ||
266 | |||
267 | free(k); | ||
268 | } | ||
269 | |||
270 | static int | ||
271 | cert_compare(struct KeyCert *a, struct KeyCert *b) | ||
272 | { | ||
273 | if (a == NULL && b == NULL) | ||
274 | return 1; | ||
275 | if (a == NULL || b == NULL) | ||
276 | return 0; | ||
277 | if (buffer_len(&a->certblob) != buffer_len(&b->certblob)) | ||
278 | return 0; | ||
279 | if (timingsafe_bcmp(buffer_ptr(&a->certblob), buffer_ptr(&b->certblob), | ||
280 | buffer_len(&a->certblob)) != 0) | ||
281 | return 0; | ||
282 | return 1; | ||
283 | } | ||
284 | |||
285 | /* | ||
286 | * Compare public portions of key only, allowing comparisons between | ||
287 | * certificates and plain keys too. | ||
288 | */ | ||
289 | int | ||
290 | key_equal_public(const Key *a, const Key *b) | ||
291 | { | ||
292 | #ifdef OPENSSL_HAS_ECC | ||
293 | BN_CTX *bnctx; | ||
294 | #endif | ||
295 | 36 | ||
296 | if (a == NULL || b == NULL || | 37 | if ((ret = sshkey_new_private(type)) == NULL) |
297 | key_type_plain(a->type) != key_type_plain(b->type)) | 38 | fatal("%s: failed", __func__); |
298 | return 0; | 39 | return ret; |
299 | |||
300 | switch (a->type) { | ||
301 | case KEY_RSA1: | ||
302 | case KEY_RSA_CERT_V00: | ||
303 | case KEY_RSA_CERT: | ||
304 | case KEY_RSA: | ||
305 | return a->rsa != NULL && b->rsa != NULL && | ||
306 | BN_cmp(a->rsa->e, b->rsa->e) == 0 && | ||
307 | BN_cmp(a->rsa->n, b->rsa->n) == 0; | ||
308 | case KEY_DSA_CERT_V00: | ||
309 | case KEY_DSA_CERT: | ||
310 | case KEY_DSA: | ||
311 | return a->dsa != NULL && b->dsa != NULL && | ||
312 | BN_cmp(a->dsa->p, b->dsa->p) == 0 && | ||
313 | BN_cmp(a->dsa->q, b->dsa->q) == 0 && | ||
314 | BN_cmp(a->dsa->g, b->dsa->g) == 0 && | ||
315 | BN_cmp(a->dsa->pub_key, b->dsa->pub_key) == 0; | ||
316 | #ifdef OPENSSL_HAS_ECC | ||
317 | case KEY_ECDSA_CERT: | ||
318 | case KEY_ECDSA: | ||
319 | if (a->ecdsa == NULL || b->ecdsa == NULL || | ||
320 | EC_KEY_get0_public_key(a->ecdsa) == NULL || | ||
321 | EC_KEY_get0_public_key(b->ecdsa) == NULL) | ||
322 | return 0; | ||
323 | if ((bnctx = BN_CTX_new()) == NULL) | ||
324 | fatal("%s: BN_CTX_new failed", __func__); | ||
325 | if (EC_GROUP_cmp(EC_KEY_get0_group(a->ecdsa), | ||
326 | EC_KEY_get0_group(b->ecdsa), bnctx) != 0 || | ||
327 | EC_POINT_cmp(EC_KEY_get0_group(a->ecdsa), | ||
328 | EC_KEY_get0_public_key(a->ecdsa), | ||
329 | EC_KEY_get0_public_key(b->ecdsa), bnctx) != 0) { | ||
330 | BN_CTX_free(bnctx); | ||
331 | return 0; | ||
332 | } | ||
333 | BN_CTX_free(bnctx); | ||
334 | return 1; | ||
335 | #endif /* OPENSSL_HAS_ECC */ | ||
336 | case KEY_ED25519: | ||
337 | case KEY_ED25519_CERT: | ||
338 | return a->ed25519_pk != NULL && b->ed25519_pk != NULL && | ||
339 | memcmp(a->ed25519_pk, b->ed25519_pk, ED25519_PK_SZ) == 0; | ||
340 | default: | ||
341 | fatal("key_equal: bad key type %d", a->type); | ||
342 | } | ||
343 | /* NOTREACHED */ | ||
344 | } | ||
345 | |||
346 | int | ||
347 | key_equal(const Key *a, const Key *b) | ||
348 | { | ||
349 | if (a == NULL || b == NULL || a->type != b->type) | ||
350 | return 0; | ||
351 | if (key_is_cert(a)) { | ||
352 | if (!cert_compare(a->cert, b->cert)) | ||
353 | return 0; | ||
354 | } | ||
355 | return key_equal_public(a, b); | ||
356 | } | 40 | } |
357 | 41 | ||
358 | u_char* | 42 | u_char* |
359 | key_fingerprint_raw(const Key *k, enum fp_type dgst_type, | 43 | key_fingerprint_raw(const Key *k, enum fp_type dgst_type, |
360 | u_int *dgst_raw_length) | 44 | u_int *dgst_raw_length) |
361 | { | 45 | { |
362 | u_char *blob = NULL; | 46 | u_char *ret = NULL; |
363 | u_char *retval = NULL; | 47 | size_t dlen; |
364 | u_int len = 0; | 48 | int r; |
365 | int nlen, elen, hash_alg = -1; | 49 | |
366 | 50 | if (dgst_raw_length != NULL) | |
367 | *dgst_raw_length = 0; | 51 | *dgst_raw_length = 0; |
368 | 52 | if ((r = sshkey_fingerprint_raw(k, dgst_type, &ret, &dlen)) != 0) | |
369 | /* XXX switch to DIGEST_* directly? */ | 53 | fatal("%s: %s", __func__, ssh_err(r)); |
370 | switch (dgst_type) { | 54 | if (dlen > INT_MAX) |
371 | case SSH_FP_MD5: | 55 | fatal("%s: giant len %zu", __func__, dlen); |
372 | hash_alg = SSH_DIGEST_MD5; | 56 | *dgst_raw_length = dlen; |
373 | break; | 57 | return ret; |
374 | case SSH_FP_SHA1: | ||
375 | hash_alg = SSH_DIGEST_SHA1; | ||
376 | break; | ||
377 | case SSH_FP_SHA256: | ||
378 | hash_alg = SSH_DIGEST_SHA256; | ||
379 | break; | ||
380 | default: | ||
381 | fatal("%s: bad digest type %d", __func__, dgst_type); | ||
382 | } | ||
383 | switch (k->type) { | ||
384 | case KEY_RSA1: | ||
385 | nlen = BN_num_bytes(k->rsa->n); | ||
386 | elen = BN_num_bytes(k->rsa->e); | ||
387 | len = nlen + elen; | ||
388 | blob = xmalloc(len); | ||
389 | BN_bn2bin(k->rsa->n, blob); | ||
390 | BN_bn2bin(k->rsa->e, blob + nlen); | ||
391 | break; | ||
392 | case KEY_DSA: | ||
393 | case KEY_ECDSA: | ||
394 | case KEY_RSA: | ||
395 | case KEY_ED25519: | ||
396 | key_to_blob(k, &blob, &len); | ||
397 | break; | ||
398 | case KEY_DSA_CERT_V00: | ||
399 | case KEY_RSA_CERT_V00: | ||
400 | case KEY_DSA_CERT: | ||
401 | case KEY_ECDSA_CERT: | ||
402 | case KEY_RSA_CERT: | ||
403 | case KEY_ED25519_CERT: | ||
404 | /* We want a fingerprint of the _key_ not of the cert */ | ||
405 | to_blob(k, &blob, &len, 1); | ||
406 | break; | ||
407 | case KEY_UNSPEC: | ||
408 | return retval; | ||
409 | default: | ||
410 | fatal("%s: bad key type %d", __func__, k->type); | ||
411 | break; | ||
412 | } | ||
413 | if (blob != NULL) { | ||
414 | retval = xmalloc(SSH_DIGEST_MAX_LENGTH); | ||
415 | if ((ssh_digest_memory(hash_alg, blob, len, | ||
416 | retval, SSH_DIGEST_MAX_LENGTH)) != 0) | ||
417 | fatal("%s: digest_memory failed", __func__); | ||
418 | explicit_bzero(blob, len); | ||
419 | free(blob); | ||
420 | *dgst_raw_length = ssh_digest_bytes(hash_alg); | ||
421 | } else { | ||
422 | fatal("%s: blob is null", __func__); | ||
423 | } | ||
424 | return retval; | ||
425 | } | ||
426 | |||
427 | static char * | ||
428 | key_fingerprint_hex(u_char *dgst_raw, u_int dgst_raw_len) | ||
429 | { | ||
430 | char *retval; | ||
431 | u_int i; | ||
432 | |||
433 | retval = xcalloc(1, dgst_raw_len * 3 + 1); | ||
434 | for (i = 0; i < dgst_raw_len; i++) { | ||
435 | char hex[4]; | ||
436 | snprintf(hex, sizeof(hex), "%02x:", dgst_raw[i]); | ||
437 | strlcat(retval, hex, dgst_raw_len * 3 + 1); | ||
438 | } | ||
439 | |||
440 | /* Remove the trailing ':' character */ | ||
441 | retval[(dgst_raw_len * 3) - 1] = '\0'; | ||
442 | return retval; | ||
443 | } | ||
444 | |||
445 | static char * | ||
446 | key_fingerprint_bubblebabble(u_char *dgst_raw, u_int dgst_raw_len) | ||
447 | { | ||
448 | char vowels[] = { 'a', 'e', 'i', 'o', 'u', 'y' }; | ||
449 | char consonants[] = { 'b', 'c', 'd', 'f', 'g', 'h', 'k', 'l', 'm', | ||
450 | 'n', 'p', 'r', 's', 't', 'v', 'z', 'x' }; | ||
451 | u_int i, j = 0, rounds, seed = 1; | ||
452 | char *retval; | ||
453 | |||
454 | rounds = (dgst_raw_len / 2) + 1; | ||
455 | retval = xcalloc((rounds * 6), sizeof(char)); | ||
456 | retval[j++] = 'x'; | ||
457 | for (i = 0; i < rounds; i++) { | ||
458 | u_int idx0, idx1, idx2, idx3, idx4; | ||
459 | if ((i + 1 < rounds) || (dgst_raw_len % 2 != 0)) { | ||
460 | idx0 = (((((u_int)(dgst_raw[2 * i])) >> 6) & 3) + | ||
461 | seed) % 6; | ||
462 | idx1 = (((u_int)(dgst_raw[2 * i])) >> 2) & 15; | ||
463 | idx2 = ((((u_int)(dgst_raw[2 * i])) & 3) + | ||
464 | (seed / 6)) % 6; | ||
465 | retval[j++] = vowels[idx0]; | ||
466 | retval[j++] = consonants[idx1]; | ||
467 | retval[j++] = vowels[idx2]; | ||
468 | if ((i + 1) < rounds) { | ||
469 | idx3 = (((u_int)(dgst_raw[(2 * i) + 1])) >> 4) & 15; | ||
470 | idx4 = (((u_int)(dgst_raw[(2 * i) + 1]))) & 15; | ||
471 | retval[j++] = consonants[idx3]; | ||
472 | retval[j++] = '-'; | ||
473 | retval[j++] = consonants[idx4]; | ||
474 | seed = ((seed * 5) + | ||
475 | ((((u_int)(dgst_raw[2 * i])) * 7) + | ||
476 | ((u_int)(dgst_raw[(2 * i) + 1])))) % 36; | ||
477 | } | ||
478 | } else { | ||
479 | idx0 = seed % 6; | ||
480 | idx1 = 16; | ||
481 | idx2 = seed / 6; | ||
482 | retval[j++] = vowels[idx0]; | ||
483 | retval[j++] = consonants[idx1]; | ||
484 | retval[j++] = vowels[idx2]; | ||
485 | } | ||
486 | } | ||
487 | retval[j++] = 'x'; | ||
488 | retval[j++] = '\0'; | ||
489 | return retval; | ||
490 | } | ||
491 | |||
492 | /* | ||
493 | * Draw an ASCII-Art representing the fingerprint so human brain can | ||
494 | * profit from its built-in pattern recognition ability. | ||
495 | * This technique is called "random art" and can be found in some | ||
496 | * scientific publications like this original paper: | ||
497 | * | ||
498 | * "Hash Visualization: a New Technique to improve Real-World Security", | ||
499 | * Perrig A. and Song D., 1999, International Workshop on Cryptographic | ||
500 | * Techniques and E-Commerce (CrypTEC '99) | ||
501 | * sparrow.ece.cmu.edu/~adrian/projects/validation/validation.pdf | ||
502 | * | ||
503 | * The subject came up in a talk by Dan Kaminsky, too. | ||
504 | * | ||
505 | * If you see the picture is different, the key is different. | ||
506 | * If the picture looks the same, you still know nothing. | ||
507 | * | ||
508 | * The algorithm used here is a worm crawling over a discrete plane, | ||
509 | * leaving a trace (augmenting the field) everywhere it goes. | ||
510 | * Movement is taken from dgst_raw 2bit-wise. Bumping into walls | ||
511 | * makes the respective movement vector be ignored for this turn. | ||
512 | * Graphs are not unambiguous, because circles in graphs can be | ||
513 | * walked in either direction. | ||
514 | */ | ||
515 | |||
516 | /* | ||
517 | * Field sizes for the random art. Have to be odd, so the starting point | ||
518 | * can be in the exact middle of the picture, and FLDBASE should be >=8 . | ||
519 | * Else pictures would be too dense, and drawing the frame would | ||
520 | * fail, too, because the key type would not fit in anymore. | ||
521 | */ | ||
522 | #define FLDBASE 8 | ||
523 | #define FLDSIZE_Y (FLDBASE + 1) | ||
524 | #define FLDSIZE_X (FLDBASE * 2 + 1) | ||
525 | static char * | ||
526 | key_fingerprint_randomart(u_char *dgst_raw, u_int dgst_raw_len, const Key *k) | ||
527 | { | ||
528 | /* | ||
529 | * Chars to be used after each other every time the worm | ||
530 | * intersects with itself. Matter of taste. | ||
531 | */ | ||
532 | char *augmentation_string = " .o+=*BOX@%&#/^SE"; | ||
533 | char *retval, *p; | ||
534 | u_char field[FLDSIZE_X][FLDSIZE_Y]; | ||
535 | u_int i, b; | ||
536 | int x, y; | ||
537 | size_t len = strlen(augmentation_string) - 1; | ||
538 | |||
539 | retval = xcalloc(1, (FLDSIZE_X + 3) * (FLDSIZE_Y + 2)); | ||
540 | |||
541 | /* initialize field */ | ||
542 | memset(field, 0, FLDSIZE_X * FLDSIZE_Y * sizeof(char)); | ||
543 | x = FLDSIZE_X / 2; | ||
544 | y = FLDSIZE_Y / 2; | ||
545 | |||
546 | /* process raw key */ | ||
547 | for (i = 0; i < dgst_raw_len; i++) { | ||
548 | int input; | ||
549 | /* each byte conveys four 2-bit move commands */ | ||
550 | input = dgst_raw[i]; | ||
551 | for (b = 0; b < 4; b++) { | ||
552 | /* evaluate 2 bit, rest is shifted later */ | ||
553 | x += (input & 0x1) ? 1 : -1; | ||
554 | y += (input & 0x2) ? 1 : -1; | ||
555 | |||
556 | /* assure we are still in bounds */ | ||
557 | x = MAX(x, 0); | ||
558 | y = MAX(y, 0); | ||
559 | x = MIN(x, FLDSIZE_X - 1); | ||
560 | y = MIN(y, FLDSIZE_Y - 1); | ||
561 | |||
562 | /* augment the field */ | ||
563 | if (field[x][y] < len - 2) | ||
564 | field[x][y]++; | ||
565 | input = input >> 2; | ||
566 | } | ||
567 | } | ||
568 | |||
569 | /* mark starting point and end point*/ | ||
570 | field[FLDSIZE_X / 2][FLDSIZE_Y / 2] = len - 1; | ||
571 | field[x][y] = len; | ||
572 | |||
573 | /* fill in retval */ | ||
574 | snprintf(retval, FLDSIZE_X, "+--[%4s %4u]", key_type(k), key_size(k)); | ||
575 | p = strchr(retval, '\0'); | ||
576 | |||
577 | /* output upper border */ | ||
578 | for (i = p - retval - 1; i < FLDSIZE_X; i++) | ||
579 | *p++ = '-'; | ||
580 | *p++ = '+'; | ||
581 | *p++ = '\n'; | ||
582 | |||
583 | /* output content */ | ||
584 | for (y = 0; y < FLDSIZE_Y; y++) { | ||
585 | *p++ = '|'; | ||
586 | for (x = 0; x < FLDSIZE_X; x++) | ||
587 | *p++ = augmentation_string[MIN(field[x][y], len)]; | ||
588 | *p++ = '|'; | ||
589 | *p++ = '\n'; | ||
590 | } | ||
591 | |||
592 | /* output lower border */ | ||
593 | *p++ = '+'; | ||
594 | for (i = 0; i < FLDSIZE_X; i++) | ||
595 | *p++ = '-'; | ||
596 | *p++ = '+'; | ||
597 | |||
598 | return retval; | ||
599 | } | ||
600 | |||
601 | char * | ||
602 | key_fingerprint(const Key *k, enum fp_type dgst_type, enum fp_rep dgst_rep) | ||
603 | { | ||
604 | char *retval = NULL; | ||
605 | u_char *dgst_raw; | ||
606 | u_int dgst_raw_len; | ||
607 | |||
608 | dgst_raw = key_fingerprint_raw(k, dgst_type, &dgst_raw_len); | ||
609 | if (!dgst_raw) | ||
610 | fatal("key_fingerprint: null from key_fingerprint_raw()"); | ||
611 | switch (dgst_rep) { | ||
612 | case SSH_FP_HEX: | ||
613 | retval = key_fingerprint_hex(dgst_raw, dgst_raw_len); | ||
614 | break; | ||
615 | case SSH_FP_BUBBLEBABBLE: | ||
616 | retval = key_fingerprint_bubblebabble(dgst_raw, dgst_raw_len); | ||
617 | break; | ||
618 | case SSH_FP_RANDOMART: | ||
619 | retval = key_fingerprint_randomart(dgst_raw, dgst_raw_len, k); | ||
620 | break; | ||
621 | default: | ||
622 | fatal("key_fingerprint: bad digest representation %d", | ||
623 | dgst_rep); | ||
624 | break; | ||
625 | } | ||
626 | explicit_bzero(dgst_raw, dgst_raw_len); | ||
627 | free(dgst_raw); | ||
628 | return retval; | ||
629 | } | ||
630 | |||
631 | /* | ||
632 | * Reads a multiple-precision integer in decimal from the buffer, and advances | ||
633 | * the pointer. The integer must already be initialized. This function is | ||
634 | * permitted to modify the buffer. This leaves *cpp to point just beyond the | ||
635 | * last processed (and maybe modified) character. Note that this may modify | ||
636 | * the buffer containing the number. | ||
637 | */ | ||
638 | static int | ||
639 | read_bignum(char **cpp, BIGNUM * value) | ||
640 | { | ||
641 | char *cp = *cpp; | ||
642 | int old; | ||
643 | |||
644 | /* Skip any leading whitespace. */ | ||
645 | for (; *cp == ' ' || *cp == '\t'; cp++) | ||
646 | ; | ||
647 | |||
648 | /* Check that it begins with a decimal digit. */ | ||
649 | if (*cp < '0' || *cp > '9') | ||
650 | return 0; | ||
651 | |||
652 | /* Save starting position. */ | ||
653 | *cpp = cp; | ||
654 | |||
655 | /* Move forward until all decimal digits skipped. */ | ||
656 | for (; *cp >= '0' && *cp <= '9'; cp++) | ||
657 | ; | ||
658 | |||
659 | /* Save the old terminating character, and replace it by \0. */ | ||
660 | old = *cp; | ||
661 | *cp = 0; | ||
662 | |||
663 | /* Parse the number. */ | ||
664 | if (BN_dec2bn(&value, *cpp) == 0) | ||
665 | return 0; | ||
666 | |||
667 | /* Restore old terminating character. */ | ||
668 | *cp = old; | ||
669 | |||
670 | /* Move beyond the number and return success. */ | ||
671 | *cpp = cp; | ||
672 | return 1; | ||
673 | } | ||
674 | |||
675 | static int | ||
676 | write_bignum(FILE *f, BIGNUM *num) | ||
677 | { | ||
678 | char *buf = BN_bn2dec(num); | ||
679 | if (buf == NULL) { | ||
680 | error("write_bignum: BN_bn2dec() failed"); | ||
681 | return 0; | ||
682 | } | ||
683 | fprintf(f, " %s", buf); | ||
684 | OPENSSL_free(buf); | ||
685 | return 1; | ||
686 | } | 58 | } |
687 | 59 | ||
688 | /* returns 1 ok, -1 error */ | ||
689 | int | 60 | int |
690 | key_read(Key *ret, char **cpp) | 61 | key_read(Key *ret, char **cpp) |
691 | { | 62 | { |
692 | Key *k; | 63 | return sshkey_read(ret, cpp) == 0 ? 1 : -1; |
693 | int success = -1; | ||
694 | char *cp, *space; | ||
695 | int len, n, type; | ||
696 | u_int bits; | ||
697 | u_char *blob; | ||
698 | #ifdef OPENSSL_HAS_ECC | ||
699 | int curve_nid = -1; | ||
700 | #endif | ||
701 | |||
702 | cp = *cpp; | ||
703 | |||
704 | switch (ret->type) { | ||
705 | case KEY_RSA1: | ||
706 | /* Get number of bits. */ | ||
707 | if (*cp < '0' || *cp > '9') | ||
708 | return -1; /* Bad bit count... */ | ||
709 | for (bits = 0; *cp >= '0' && *cp <= '9'; cp++) | ||
710 | bits = 10 * bits + *cp - '0'; | ||
711 | if (bits == 0) | ||
712 | return -1; | ||
713 | *cpp = cp; | ||
714 | /* Get public exponent, public modulus. */ | ||
715 | if (!read_bignum(cpp, ret->rsa->e)) | ||
716 | return -1; | ||
717 | if (!read_bignum(cpp, ret->rsa->n)) | ||
718 | return -1; | ||
719 | /* validate the claimed number of bits */ | ||
720 | if ((u_int)BN_num_bits(ret->rsa->n) != bits) { | ||
721 | verbose("key_read: claimed key size %d does not match " | ||
722 | "actual %d", bits, BN_num_bits(ret->rsa->n)); | ||
723 | return -1; | ||
724 | } | ||
725 | success = 1; | ||
726 | break; | ||
727 | case KEY_UNSPEC: | ||
728 | case KEY_RSA: | ||
729 | case KEY_DSA: | ||
730 | case KEY_ECDSA: | ||
731 | case KEY_ED25519: | ||
732 | case KEY_DSA_CERT_V00: | ||
733 | case KEY_RSA_CERT_V00: | ||
734 | case KEY_DSA_CERT: | ||
735 | case KEY_ECDSA_CERT: | ||
736 | case KEY_RSA_CERT: | ||
737 | case KEY_ED25519_CERT: | ||
738 | space = strchr(cp, ' '); | ||
739 | if (space == NULL) { | ||
740 | debug3("key_read: missing whitespace"); | ||
741 | return -1; | ||
742 | } | ||
743 | *space = '\0'; | ||
744 | type = key_type_from_name(cp); | ||
745 | #ifdef OPENSSL_HAS_ECC | ||
746 | if (key_type_plain(type) == KEY_ECDSA && | ||
747 | (curve_nid = key_ecdsa_nid_from_name(cp)) == -1) { | ||
748 | debug("key_read: invalid curve"); | ||
749 | return -1; | ||
750 | } | ||
751 | #endif | ||
752 | *space = ' '; | ||
753 | if (type == KEY_UNSPEC) { | ||
754 | debug3("key_read: missing keytype"); | ||
755 | return -1; | ||
756 | } | ||
757 | cp = space+1; | ||
758 | if (*cp == '\0') { | ||
759 | debug3("key_read: short string"); | ||
760 | return -1; | ||
761 | } | ||
762 | if (ret->type == KEY_UNSPEC) { | ||
763 | ret->type = type; | ||
764 | } else if (ret->type != type) { | ||
765 | /* is a key, but different type */ | ||
766 | debug3("key_read: type mismatch"); | ||
767 | return -1; | ||
768 | } | ||
769 | len = 2*strlen(cp); | ||
770 | blob = xmalloc(len); | ||
771 | n = uudecode(cp, blob, len); | ||
772 | if (n < 0) { | ||
773 | error("key_read: uudecode %s failed", cp); | ||
774 | free(blob); | ||
775 | return -1; | ||
776 | } | ||
777 | k = key_from_blob(blob, (u_int)n); | ||
778 | free(blob); | ||
779 | if (k == NULL) { | ||
780 | error("key_read: key_from_blob %s failed", cp); | ||
781 | return -1; | ||
782 | } | ||
783 | if (k->type != type) { | ||
784 | error("key_read: type mismatch: encoding error"); | ||
785 | key_free(k); | ||
786 | return -1; | ||
787 | } | ||
788 | #ifdef OPENSSL_HAS_ECC | ||
789 | if (key_type_plain(type) == KEY_ECDSA && | ||
790 | curve_nid != k->ecdsa_nid) { | ||
791 | error("key_read: type mismatch: EC curve mismatch"); | ||
792 | key_free(k); | ||
793 | return -1; | ||
794 | } | ||
795 | #endif | ||
796 | /*XXXX*/ | ||
797 | if (key_is_cert(ret)) { | ||
798 | if (!key_is_cert(k)) { | ||
799 | error("key_read: loaded key is not a cert"); | ||
800 | key_free(k); | ||
801 | return -1; | ||
802 | } | ||
803 | if (ret->cert != NULL) | ||
804 | cert_free(ret->cert); | ||
805 | ret->cert = k->cert; | ||
806 | k->cert = NULL; | ||
807 | } | ||
808 | if (key_type_plain(ret->type) == KEY_RSA) { | ||
809 | if (ret->rsa != NULL) | ||
810 | RSA_free(ret->rsa); | ||
811 | ret->rsa = k->rsa; | ||
812 | k->rsa = NULL; | ||
813 | #ifdef DEBUG_PK | ||
814 | RSA_print_fp(stderr, ret->rsa, 8); | ||
815 | #endif | ||
816 | } | ||
817 | if (key_type_plain(ret->type) == KEY_DSA) { | ||
818 | if (ret->dsa != NULL) | ||
819 | DSA_free(ret->dsa); | ||
820 | ret->dsa = k->dsa; | ||
821 | k->dsa = NULL; | ||
822 | #ifdef DEBUG_PK | ||
823 | DSA_print_fp(stderr, ret->dsa, 8); | ||
824 | #endif | ||
825 | } | ||
826 | #ifdef OPENSSL_HAS_ECC | ||
827 | if (key_type_plain(ret->type) == KEY_ECDSA) { | ||
828 | if (ret->ecdsa != NULL) | ||
829 | EC_KEY_free(ret->ecdsa); | ||
830 | ret->ecdsa = k->ecdsa; | ||
831 | ret->ecdsa_nid = k->ecdsa_nid; | ||
832 | k->ecdsa = NULL; | ||
833 | k->ecdsa_nid = -1; | ||
834 | #ifdef DEBUG_PK | ||
835 | key_dump_ec_key(ret->ecdsa); | ||
836 | #endif | ||
837 | } | ||
838 | #endif | ||
839 | if (key_type_plain(ret->type) == KEY_ED25519) { | ||
840 | free(ret->ed25519_pk); | ||
841 | ret->ed25519_pk = k->ed25519_pk; | ||
842 | k->ed25519_pk = NULL; | ||
843 | #ifdef DEBUG_PK | ||
844 | /* XXX */ | ||
845 | #endif | ||
846 | } | ||
847 | success = 1; | ||
848 | /*XXXX*/ | ||
849 | key_free(k); | ||
850 | if (success != 1) | ||
851 | break; | ||
852 | /* advance cp: skip whitespace and data */ | ||
853 | while (*cp == ' ' || *cp == '\t') | ||
854 | cp++; | ||
855 | while (*cp != '\0' && *cp != ' ' && *cp != '\t') | ||
856 | cp++; | ||
857 | *cpp = cp; | ||
858 | break; | ||
859 | default: | ||
860 | fatal("key_read: bad key type: %d", ret->type); | ||
861 | break; | ||
862 | } | ||
863 | return success; | ||
864 | } | 64 | } |
865 | 65 | ||
866 | int | 66 | int |
867 | key_write(const Key *key, FILE *f) | 67 | key_write(const Key *key, FILE *f) |
868 | { | 68 | { |
869 | int n, success = 0; | 69 | return sshkey_write(key, f) == 0 ? 1 : 0; |
870 | u_int len, bits = 0; | ||
871 | u_char *blob; | ||
872 | char *uu; | ||
873 | |||
874 | if (key_is_cert(key)) { | ||
875 | if (key->cert == NULL) { | ||
876 | error("%s: no cert data", __func__); | ||
877 | return 0; | ||
878 | } | ||
879 | if (buffer_len(&key->cert->certblob) == 0) { | ||
880 | error("%s: no signed certificate blob", __func__); | ||
881 | return 0; | ||
882 | } | ||
883 | } | ||
884 | |||
885 | switch (key->type) { | ||
886 | case KEY_RSA1: | ||
887 | if (key->rsa == NULL) | ||
888 | return 0; | ||
889 | /* size of modulus 'n' */ | ||
890 | bits = BN_num_bits(key->rsa->n); | ||
891 | fprintf(f, "%u", bits); | ||
892 | if (write_bignum(f, key->rsa->e) && | ||
893 | write_bignum(f, key->rsa->n)) | ||
894 | return 1; | ||
895 | error("key_write: failed for RSA key"); | ||
896 | return 0; | ||
897 | case KEY_DSA: | ||
898 | case KEY_DSA_CERT_V00: | ||
899 | case KEY_DSA_CERT: | ||
900 | if (key->dsa == NULL) | ||
901 | return 0; | ||
902 | break; | ||
903 | #ifdef OPENSSL_HAS_ECC | ||
904 | case KEY_ECDSA: | ||
905 | case KEY_ECDSA_CERT: | ||
906 | if (key->ecdsa == NULL) | ||
907 | return 0; | ||
908 | break; | ||
909 | #endif | ||
910 | case KEY_ED25519: | ||
911 | case KEY_ED25519_CERT: | ||
912 | if (key->ed25519_pk == NULL) | ||
913 | return 0; | ||
914 | break; | ||
915 | case KEY_RSA: | ||
916 | case KEY_RSA_CERT_V00: | ||
917 | case KEY_RSA_CERT: | ||
918 | if (key->rsa == NULL) | ||
919 | return 0; | ||
920 | break; | ||
921 | default: | ||
922 | return 0; | ||
923 | } | ||
924 | |||
925 | key_to_blob(key, &blob, &len); | ||
926 | uu = xmalloc(2*len); | ||
927 | n = uuencode(blob, len, uu, 2*len); | ||
928 | if (n > 0) { | ||
929 | fprintf(f, "%s %s", key_ssh_name(key), uu); | ||
930 | success = 1; | ||
931 | } | ||
932 | free(blob); | ||
933 | free(uu); | ||
934 | |||
935 | return success; | ||
936 | } | ||
937 | |||
938 | const char * | ||
939 | key_cert_type(const Key *k) | ||
940 | { | ||
941 | switch (k->cert->type) { | ||
942 | case SSH2_CERT_TYPE_USER: | ||
943 | return "user"; | ||
944 | case SSH2_CERT_TYPE_HOST: | ||
945 | return "host"; | ||
946 | default: | ||
947 | return "unknown"; | ||
948 | } | ||
949 | } | ||
950 | |||
951 | struct keytype { | ||
952 | char *name; | ||
953 | char *shortname; | ||
954 | int type; | ||
955 | int nid; | ||
956 | int cert; | ||
957 | }; | ||
958 | static const struct keytype keytypes[] = { | ||
959 | { NULL, "RSA1", KEY_RSA1, 0, 0 }, | ||
960 | { "ssh-rsa", "RSA", KEY_RSA, 0, 0 }, | ||
961 | { "ssh-dss", "DSA", KEY_DSA, 0, 0 }, | ||
962 | { "ssh-ed25519", "ED25519", KEY_ED25519, 0, 0 }, | ||
963 | #ifdef OPENSSL_HAS_ECC | ||
964 | { "ecdsa-sha2-nistp256", "ECDSA", KEY_ECDSA, NID_X9_62_prime256v1, 0 }, | ||
965 | { "ecdsa-sha2-nistp384", "ECDSA", KEY_ECDSA, NID_secp384r1, 0 }, | ||
966 | # ifdef OPENSSL_HAS_NISTP521 | ||
967 | { "ecdsa-sha2-nistp521", "ECDSA", KEY_ECDSA, NID_secp521r1, 0 }, | ||
968 | # endif | ||
969 | #endif /* OPENSSL_HAS_ECC */ | ||
970 | { "ssh-rsa-cert-v01@openssh.com", "RSA-CERT", KEY_RSA_CERT, 0, 1 }, | ||
971 | { "ssh-dss-cert-v01@openssh.com", "DSA-CERT", KEY_DSA_CERT, 0, 1 }, | ||
972 | #ifdef OPENSSL_HAS_ECC | ||
973 | { "ecdsa-sha2-nistp256-cert-v01@openssh.com", "ECDSA-CERT", | ||
974 | KEY_ECDSA_CERT, NID_X9_62_prime256v1, 1 }, | ||
975 | { "ecdsa-sha2-nistp384-cert-v01@openssh.com", "ECDSA-CERT", | ||
976 | KEY_ECDSA_CERT, NID_secp384r1, 1 }, | ||
977 | # ifdef OPENSSL_HAS_NISTP521 | ||
978 | { "ecdsa-sha2-nistp521-cert-v01@openssh.com", "ECDSA-CERT", | ||
979 | KEY_ECDSA_CERT, NID_secp521r1, 1 }, | ||
980 | # endif | ||
981 | #endif /* OPENSSL_HAS_ECC */ | ||
982 | { "ssh-rsa-cert-v00@openssh.com", "RSA-CERT-V00", | ||
983 | KEY_RSA_CERT_V00, 0, 1 }, | ||
984 | { "ssh-dss-cert-v00@openssh.com", "DSA-CERT-V00", | ||
985 | KEY_DSA_CERT_V00, 0, 1 }, | ||
986 | { "ssh-ed25519-cert-v01@openssh.com", "ED25519-CERT", | ||
987 | KEY_ED25519_CERT, 0, 1 }, | ||
988 | { "null", "null", KEY_NULL, 0, 0 }, | ||
989 | { NULL, NULL, -1, -1, 0 } | ||
990 | }; | ||
991 | |||
992 | const char * | ||
993 | key_type(const Key *k) | ||
994 | { | ||
995 | const struct keytype *kt; | ||
996 | |||
997 | for (kt = keytypes; kt->type != -1; kt++) { | ||
998 | if (kt->type == k->type) | ||
999 | return kt->shortname; | ||
1000 | } | ||
1001 | return "unknown"; | ||
1002 | } | ||
1003 | |||
1004 | static const char * | ||
1005 | key_ssh_name_from_type_nid(int type, int nid) | ||
1006 | { | ||
1007 | const struct keytype *kt; | ||
1008 | |||
1009 | for (kt = keytypes; kt->type != -1; kt++) { | ||
1010 | if (kt->type == type && (kt->nid == 0 || kt->nid == nid)) | ||
1011 | return kt->name; | ||
1012 | } | ||
1013 | return "ssh-unknown"; | ||
1014 | } | ||
1015 | |||
1016 | const char * | ||
1017 | key_ssh_name(const Key *k) | ||
1018 | { | ||
1019 | return key_ssh_name_from_type_nid(k->type, k->ecdsa_nid); | ||
1020 | } | ||
1021 | |||
1022 | const char * | ||
1023 | key_ssh_name_plain(const Key *k) | ||
1024 | { | ||
1025 | return key_ssh_name_from_type_nid(key_type_plain(k->type), | ||
1026 | k->ecdsa_nid); | ||
1027 | } | ||
1028 | |||
1029 | int | ||
1030 | key_type_from_name(char *name) | ||
1031 | { | ||
1032 | const struct keytype *kt; | ||
1033 | |||
1034 | for (kt = keytypes; kt->type != -1; kt++) { | ||
1035 | /* Only allow shortname matches for plain key types */ | ||
1036 | if ((kt->name != NULL && strcmp(name, kt->name) == 0) || | ||
1037 | (!kt->cert && strcasecmp(kt->shortname, name) == 0)) | ||
1038 | return kt->type; | ||
1039 | } | ||
1040 | debug2("key_type_from_name: unknown key type '%s'", name); | ||
1041 | return KEY_UNSPEC; | ||
1042 | } | ||
1043 | |||
1044 | int | ||
1045 | key_ecdsa_nid_from_name(const char *name) | ||
1046 | { | ||
1047 | const struct keytype *kt; | ||
1048 | |||
1049 | for (kt = keytypes; kt->type != -1; kt++) { | ||
1050 | if (kt->type != KEY_ECDSA && kt->type != KEY_ECDSA_CERT) | ||
1051 | continue; | ||
1052 | if (kt->name != NULL && strcmp(name, kt->name) == 0) | ||
1053 | return kt->nid; | ||
1054 | } | ||
1055 | debug2("%s: unknown/non-ECDSA key type '%s'", __func__, name); | ||
1056 | return -1; | ||
1057 | } | ||
1058 | |||
1059 | char * | ||
1060 | key_alg_list(int certs_only, int plain_only) | ||
1061 | { | ||
1062 | char *ret = NULL; | ||
1063 | size_t nlen, rlen = 0; | ||
1064 | const struct keytype *kt; | ||
1065 | |||
1066 | for (kt = keytypes; kt->type != -1; kt++) { | ||
1067 | if (kt->name == NULL || kt->type == KEY_NULL) | ||
1068 | continue; | ||
1069 | if ((certs_only && !kt->cert) || (plain_only && kt->cert)) | ||
1070 | continue; | ||
1071 | if (ret != NULL) | ||
1072 | ret[rlen++] = '\n'; | ||
1073 | nlen = strlen(kt->name); | ||
1074 | ret = xrealloc(ret, 1, rlen + nlen + 2); | ||
1075 | memcpy(ret + rlen, kt->name, nlen + 1); | ||
1076 | rlen += nlen; | ||
1077 | } | ||
1078 | return ret; | ||
1079 | } | ||
1080 | |||
1081 | int | ||
1082 | key_type_is_cert(int type) | ||
1083 | { | ||
1084 | const struct keytype *kt; | ||
1085 | |||
1086 | for (kt = keytypes; kt->type != -1; kt++) { | ||
1087 | if (kt->type == type) | ||
1088 | return kt->cert; | ||
1089 | } | ||
1090 | return 0; | ||
1091 | } | ||
1092 | |||
1093 | static int | ||
1094 | key_type_is_valid_ca(int type) | ||
1095 | { | ||
1096 | switch (type) { | ||
1097 | case KEY_RSA: | ||
1098 | case KEY_DSA: | ||
1099 | case KEY_ECDSA: | ||
1100 | case KEY_ED25519: | ||
1101 | return 1; | ||
1102 | default: | ||
1103 | return 0; | ||
1104 | } | ||
1105 | } | ||
1106 | |||
1107 | u_int | ||
1108 | key_size(const Key *k) | ||
1109 | { | ||
1110 | switch (k->type) { | ||
1111 | case KEY_RSA1: | ||
1112 | case KEY_RSA: | ||
1113 | case KEY_RSA_CERT_V00: | ||
1114 | case KEY_RSA_CERT: | ||
1115 | return BN_num_bits(k->rsa->n); | ||
1116 | case KEY_DSA: | ||
1117 | case KEY_DSA_CERT_V00: | ||
1118 | case KEY_DSA_CERT: | ||
1119 | return BN_num_bits(k->dsa->p); | ||
1120 | case KEY_ED25519: | ||
1121 | return 256; /* XXX */ | ||
1122 | #ifdef OPENSSL_HAS_ECC | ||
1123 | case KEY_ECDSA: | ||
1124 | case KEY_ECDSA_CERT: | ||
1125 | return key_curve_nid_to_bits(k->ecdsa_nid); | ||
1126 | #endif | ||
1127 | } | ||
1128 | return 0; | ||
1129 | } | ||
1130 | |||
1131 | static RSA * | ||
1132 | rsa_generate_private_key(u_int bits) | ||
1133 | { | ||
1134 | RSA *private = RSA_new(); | ||
1135 | BIGNUM *f4 = BN_new(); | ||
1136 | |||
1137 | if (private == NULL) | ||
1138 | fatal("%s: RSA_new failed", __func__); | ||
1139 | if (f4 == NULL) | ||
1140 | fatal("%s: BN_new failed", __func__); | ||
1141 | if (!BN_set_word(f4, RSA_F4)) | ||
1142 | fatal("%s: BN_new failed", __func__); | ||
1143 | if (!RSA_generate_key_ex(private, bits, f4, NULL)) | ||
1144 | fatal("%s: key generation failed.", __func__); | ||
1145 | BN_free(f4); | ||
1146 | return private; | ||
1147 | } | ||
1148 | |||
1149 | static DSA* | ||
1150 | dsa_generate_private_key(u_int bits) | ||
1151 | { | ||
1152 | DSA *private = DSA_new(); | ||
1153 | |||
1154 | if (private == NULL) | ||
1155 | fatal("%s: DSA_new failed", __func__); | ||
1156 | if (!DSA_generate_parameters_ex(private, bits, NULL, 0, NULL, | ||
1157 | NULL, NULL)) | ||
1158 | fatal("%s: DSA_generate_parameters failed", __func__); | ||
1159 | if (!DSA_generate_key(private)) | ||
1160 | fatal("%s: DSA_generate_key failed.", __func__); | ||
1161 | return private; | ||
1162 | } | ||
1163 | |||
1164 | int | ||
1165 | key_ecdsa_bits_to_nid(int bits) | ||
1166 | { | ||
1167 | switch (bits) { | ||
1168 | #ifdef OPENSSL_HAS_ECC | ||
1169 | case 256: | ||
1170 | return NID_X9_62_prime256v1; | ||
1171 | case 384: | ||
1172 | return NID_secp384r1; | ||
1173 | # ifdef OPENSSL_HAS_NISTP521 | ||
1174 | case 521: | ||
1175 | return NID_secp521r1; | ||
1176 | # endif | ||
1177 | #endif | ||
1178 | default: | ||
1179 | return -1; | ||
1180 | } | ||
1181 | } | ||
1182 | |||
1183 | #ifdef OPENSSL_HAS_ECC | ||
1184 | int | ||
1185 | key_ecdsa_key_to_nid(EC_KEY *k) | ||
1186 | { | ||
1187 | EC_GROUP *eg; | ||
1188 | int nids[] = { | ||
1189 | NID_X9_62_prime256v1, | ||
1190 | NID_secp384r1, | ||
1191 | # ifdef OPENSSL_HAS_NISTP521 | ||
1192 | NID_secp521r1, | ||
1193 | # endif | ||
1194 | -1 | ||
1195 | }; | ||
1196 | int nid; | ||
1197 | u_int i; | ||
1198 | BN_CTX *bnctx; | ||
1199 | const EC_GROUP *g = EC_KEY_get0_group(k); | ||
1200 | |||
1201 | /* | ||
1202 | * The group may be stored in a ASN.1 encoded private key in one of two | ||
1203 | * ways: as a "named group", which is reconstituted by ASN.1 object ID | ||
1204 | * or explicit group parameters encoded into the key blob. Only the | ||
1205 | * "named group" case sets the group NID for us, but we can figure | ||
1206 | * it out for the other case by comparing against all the groups that | ||
1207 | * are supported. | ||
1208 | */ | ||
1209 | if ((nid = EC_GROUP_get_curve_name(g)) > 0) | ||
1210 | return nid; | ||
1211 | if ((bnctx = BN_CTX_new()) == NULL) | ||
1212 | fatal("%s: BN_CTX_new() failed", __func__); | ||
1213 | for (i = 0; nids[i] != -1; i++) { | ||
1214 | if ((eg = EC_GROUP_new_by_curve_name(nids[i])) == NULL) | ||
1215 | fatal("%s: EC_GROUP_new_by_curve_name failed", | ||
1216 | __func__); | ||
1217 | if (EC_GROUP_cmp(g, eg, bnctx) == 0) | ||
1218 | break; | ||
1219 | EC_GROUP_free(eg); | ||
1220 | } | ||
1221 | BN_CTX_free(bnctx); | ||
1222 | debug3("%s: nid = %d", __func__, nids[i]); | ||
1223 | if (nids[i] != -1) { | ||
1224 | /* Use the group with the NID attached */ | ||
1225 | EC_GROUP_set_asn1_flag(eg, OPENSSL_EC_NAMED_CURVE); | ||
1226 | if (EC_KEY_set_group(k, eg) != 1) | ||
1227 | fatal("%s: EC_KEY_set_group", __func__); | ||
1228 | } | ||
1229 | return nids[i]; | ||
1230 | } | ||
1231 | |||
1232 | static EC_KEY* | ||
1233 | ecdsa_generate_private_key(u_int bits, int *nid) | ||
1234 | { | ||
1235 | EC_KEY *private; | ||
1236 | |||
1237 | if ((*nid = key_ecdsa_bits_to_nid(bits)) == -1) | ||
1238 | fatal("%s: invalid key length", __func__); | ||
1239 | if ((private = EC_KEY_new_by_curve_name(*nid)) == NULL) | ||
1240 | fatal("%s: EC_KEY_new_by_curve_name failed", __func__); | ||
1241 | if (EC_KEY_generate_key(private) != 1) | ||
1242 | fatal("%s: EC_KEY_generate_key failed", __func__); | ||
1243 | EC_KEY_set_asn1_flag(private, OPENSSL_EC_NAMED_CURVE); | ||
1244 | return private; | ||
1245 | } | 70 | } |
1246 | #endif /* OPENSSL_HAS_ECC */ | ||
1247 | 71 | ||
1248 | Key * | 72 | Key * |
1249 | key_generate(int type, u_int bits) | 73 | key_generate(int type, u_int bits) |
1250 | { | 74 | { |
1251 | Key *k = key_new(KEY_UNSPEC); | 75 | int r; |
1252 | switch (type) { | 76 | Key *ret = NULL; |
1253 | case KEY_DSA: | 77 | |
1254 | k->dsa = dsa_generate_private_key(bits); | 78 | if ((r = sshkey_generate(type, bits, &ret)) != 0) |
1255 | break; | 79 | fatal("%s: %s", __func__, ssh_err(r)); |
1256 | #ifdef OPENSSL_HAS_ECC | 80 | return ret; |
1257 | case KEY_ECDSA: | ||
1258 | k->ecdsa = ecdsa_generate_private_key(bits, &k->ecdsa_nid); | ||
1259 | break; | ||
1260 | #endif | ||
1261 | case KEY_RSA: | ||
1262 | case KEY_RSA1: | ||
1263 | k->rsa = rsa_generate_private_key(bits); | ||
1264 | break; | ||
1265 | case KEY_ED25519: | ||
1266 | k->ed25519_pk = xmalloc(ED25519_PK_SZ); | ||
1267 | k->ed25519_sk = xmalloc(ED25519_SK_SZ); | ||
1268 | crypto_sign_ed25519_keypair(k->ed25519_pk, k->ed25519_sk); | ||
1269 | break; | ||
1270 | case KEY_RSA_CERT_V00: | ||
1271 | case KEY_DSA_CERT_V00: | ||
1272 | case KEY_RSA_CERT: | ||
1273 | case KEY_DSA_CERT: | ||
1274 | fatal("key_generate: cert keys cannot be generated directly"); | ||
1275 | default: | ||
1276 | fatal("key_generate: unknown type %d", type); | ||
1277 | } | ||
1278 | k->type = type; | ||
1279 | return k; | ||
1280 | } | 81 | } |
1281 | 82 | ||
1282 | void | 83 | void |
1283 | key_cert_copy(const Key *from_key, struct Key *to_key) | 84 | key_cert_copy(const Key *from_key, Key *to_key) |
1284 | { | 85 | { |
1285 | u_int i; | 86 | int r; |
1286 | const struct KeyCert *from; | ||
1287 | struct KeyCert *to; | ||
1288 | |||
1289 | if (to_key->cert != NULL) { | ||
1290 | cert_free(to_key->cert); | ||
1291 | to_key->cert = NULL; | ||
1292 | } | ||
1293 | 87 | ||
1294 | if ((from = from_key->cert) == NULL) | 88 | if ((r = sshkey_cert_copy(from_key, to_key)) != 0) |
1295 | return; | 89 | fatal("%s: %s", __func__, ssh_err(r)); |
1296 | |||
1297 | to = to_key->cert = cert_new(); | ||
1298 | |||
1299 | buffer_append(&to->certblob, buffer_ptr(&from->certblob), | ||
1300 | buffer_len(&from->certblob)); | ||
1301 | |||
1302 | buffer_append(&to->critical, | ||
1303 | buffer_ptr(&from->critical), buffer_len(&from->critical)); | ||
1304 | buffer_append(&to->extensions, | ||
1305 | buffer_ptr(&from->extensions), buffer_len(&from->extensions)); | ||
1306 | |||
1307 | to->serial = from->serial; | ||
1308 | to->type = from->type; | ||
1309 | to->key_id = from->key_id == NULL ? NULL : xstrdup(from->key_id); | ||
1310 | to->valid_after = from->valid_after; | ||
1311 | to->valid_before = from->valid_before; | ||
1312 | to->signature_key = from->signature_key == NULL ? | ||
1313 | NULL : key_from_private(from->signature_key); | ||
1314 | |||
1315 | to->nprincipals = from->nprincipals; | ||
1316 | if (to->nprincipals > CERT_MAX_PRINCIPALS) | ||
1317 | fatal("%s: nprincipals (%u) > CERT_MAX_PRINCIPALS (%u)", | ||
1318 | __func__, to->nprincipals, CERT_MAX_PRINCIPALS); | ||
1319 | if (to->nprincipals > 0) { | ||
1320 | to->principals = xcalloc(from->nprincipals, | ||
1321 | sizeof(*to->principals)); | ||
1322 | for (i = 0; i < to->nprincipals; i++) | ||
1323 | to->principals[i] = xstrdup(from->principals[i]); | ||
1324 | } | ||
1325 | } | 90 | } |
1326 | 91 | ||
1327 | Key * | 92 | Key * |
1328 | key_from_private(const Key *k) | 93 | key_from_private(const Key *k) |
1329 | { | 94 | { |
1330 | Key *n = NULL; | 95 | int r; |
1331 | switch (k->type) { | 96 | Key *ret = NULL; |
1332 | case KEY_DSA: | ||
1333 | case KEY_DSA_CERT_V00: | ||
1334 | case KEY_DSA_CERT: | ||
1335 | n = key_new(k->type); | ||
1336 | if ((BN_copy(n->dsa->p, k->dsa->p) == NULL) || | ||
1337 | (BN_copy(n->dsa->q, k->dsa->q) == NULL) || | ||
1338 | (BN_copy(n->dsa->g, k->dsa->g) == NULL) || | ||
1339 | (BN_copy(n->dsa->pub_key, k->dsa->pub_key) == NULL)) | ||
1340 | fatal("key_from_private: BN_copy failed"); | ||
1341 | break; | ||
1342 | #ifdef OPENSSL_HAS_ECC | ||
1343 | case KEY_ECDSA: | ||
1344 | case KEY_ECDSA_CERT: | ||
1345 | n = key_new(k->type); | ||
1346 | n->ecdsa_nid = k->ecdsa_nid; | ||
1347 | if ((n->ecdsa = EC_KEY_new_by_curve_name(k->ecdsa_nid)) == NULL) | ||
1348 | fatal("%s: EC_KEY_new_by_curve_name failed", __func__); | ||
1349 | if (EC_KEY_set_public_key(n->ecdsa, | ||
1350 | EC_KEY_get0_public_key(k->ecdsa)) != 1) | ||
1351 | fatal("%s: EC_KEY_set_public_key failed", __func__); | ||
1352 | break; | ||
1353 | #endif | ||
1354 | case KEY_RSA: | ||
1355 | case KEY_RSA1: | ||
1356 | case KEY_RSA_CERT_V00: | ||
1357 | case KEY_RSA_CERT: | ||
1358 | n = key_new(k->type); | ||
1359 | if ((BN_copy(n->rsa->n, k->rsa->n) == NULL) || | ||
1360 | (BN_copy(n->rsa->e, k->rsa->e) == NULL)) | ||
1361 | fatal("key_from_private: BN_copy failed"); | ||
1362 | break; | ||
1363 | case KEY_ED25519: | ||
1364 | case KEY_ED25519_CERT: | ||
1365 | n = key_new(k->type); | ||
1366 | if (k->ed25519_pk != NULL) { | ||
1367 | n->ed25519_pk = xmalloc(ED25519_PK_SZ); | ||
1368 | memcpy(n->ed25519_pk, k->ed25519_pk, ED25519_PK_SZ); | ||
1369 | } | ||
1370 | break; | ||
1371 | default: | ||
1372 | fatal("key_from_private: unknown type %d", k->type); | ||
1373 | break; | ||
1374 | } | ||
1375 | if (key_is_cert(k)) | ||
1376 | key_cert_copy(k, n); | ||
1377 | return n; | ||
1378 | } | ||
1379 | |||
1380 | int | ||
1381 | key_names_valid2(const char *names) | ||
1382 | { | ||
1383 | char *s, *cp, *p; | ||
1384 | |||
1385 | if (names == NULL || strcmp(names, "") == 0) | ||
1386 | return 0; | ||
1387 | s = cp = xstrdup(names); | ||
1388 | for ((p = strsep(&cp, ",")); p && *p != '\0'; | ||
1389 | (p = strsep(&cp, ","))) { | ||
1390 | switch (key_type_from_name(p)) { | ||
1391 | case KEY_RSA1: | ||
1392 | case KEY_UNSPEC: | ||
1393 | free(s); | ||
1394 | return 0; | ||
1395 | } | ||
1396 | } | ||
1397 | debug3("key names ok: [%s]", names); | ||
1398 | free(s); | ||
1399 | return 1; | ||
1400 | } | ||
1401 | |||
1402 | static int | ||
1403 | cert_parse(Buffer *b, Key *key, const u_char *blob, u_int blen) | ||
1404 | { | ||
1405 | u_char *principals, *critical, *exts, *sig_key, *sig; | ||
1406 | u_int signed_len, plen, clen, sklen, slen, kidlen, elen; | ||
1407 | Buffer tmp; | ||
1408 | char *principal; | ||
1409 | int ret = -1; | ||
1410 | int v00 = key->type == KEY_DSA_CERT_V00 || | ||
1411 | key->type == KEY_RSA_CERT_V00; | ||
1412 | |||
1413 | buffer_init(&tmp); | ||
1414 | |||
1415 | /* Copy the entire key blob for verification and later serialisation */ | ||
1416 | buffer_append(&key->cert->certblob, blob, blen); | ||
1417 | |||
1418 | elen = 0; /* Not touched for v00 certs */ | ||
1419 | principals = exts = critical = sig_key = sig = NULL; | ||
1420 | if ((!v00 && buffer_get_int64_ret(&key->cert->serial, b) != 0) || | ||
1421 | buffer_get_int_ret(&key->cert->type, b) != 0 || | ||
1422 | (key->cert->key_id = buffer_get_cstring_ret(b, &kidlen)) == NULL || | ||
1423 | (principals = buffer_get_string_ret(b, &plen)) == NULL || | ||
1424 | buffer_get_int64_ret(&key->cert->valid_after, b) != 0 || | ||
1425 | buffer_get_int64_ret(&key->cert->valid_before, b) != 0 || | ||
1426 | (critical = buffer_get_string_ret(b, &clen)) == NULL || | ||
1427 | (!v00 && (exts = buffer_get_string_ret(b, &elen)) == NULL) || | ||
1428 | (v00 && buffer_get_string_ptr_ret(b, NULL) == NULL) || /* nonce */ | ||
1429 | buffer_get_string_ptr_ret(b, NULL) == NULL || /* reserved */ | ||
1430 | (sig_key = buffer_get_string_ret(b, &sklen)) == NULL) { | ||
1431 | error("%s: parse error", __func__); | ||
1432 | goto out; | ||
1433 | } | ||
1434 | |||
1435 | /* Signature is left in the buffer so we can calculate this length */ | ||
1436 | signed_len = buffer_len(&key->cert->certblob) - buffer_len(b); | ||
1437 | |||
1438 | if ((sig = buffer_get_string_ret(b, &slen)) == NULL) { | ||
1439 | error("%s: parse error", __func__); | ||
1440 | goto out; | ||
1441 | } | ||
1442 | |||
1443 | if (key->cert->type != SSH2_CERT_TYPE_USER && | ||
1444 | key->cert->type != SSH2_CERT_TYPE_HOST) { | ||
1445 | error("Unknown certificate type %u", key->cert->type); | ||
1446 | goto out; | ||
1447 | } | ||
1448 | 97 | ||
1449 | buffer_append(&tmp, principals, plen); | 98 | if ((r = sshkey_from_private(k, &ret)) != 0) |
1450 | while (buffer_len(&tmp) > 0) { | 99 | fatal("%s: %s", __func__, ssh_err(r)); |
1451 | if (key->cert->nprincipals >= CERT_MAX_PRINCIPALS) { | ||
1452 | error("%s: Too many principals", __func__); | ||
1453 | goto out; | ||
1454 | } | ||
1455 | if ((principal = buffer_get_cstring_ret(&tmp, &plen)) == NULL) { | ||
1456 | error("%s: Principals data invalid", __func__); | ||
1457 | goto out; | ||
1458 | } | ||
1459 | key->cert->principals = xrealloc(key->cert->principals, | ||
1460 | key->cert->nprincipals + 1, sizeof(*key->cert->principals)); | ||
1461 | key->cert->principals[key->cert->nprincipals++] = principal; | ||
1462 | } | ||
1463 | |||
1464 | buffer_clear(&tmp); | ||
1465 | |||
1466 | buffer_append(&key->cert->critical, critical, clen); | ||
1467 | buffer_append(&tmp, critical, clen); | ||
1468 | /* validate structure */ | ||
1469 | while (buffer_len(&tmp) != 0) { | ||
1470 | if (buffer_get_string_ptr_ret(&tmp, NULL) == NULL || | ||
1471 | buffer_get_string_ptr_ret(&tmp, NULL) == NULL) { | ||
1472 | error("%s: critical option data invalid", __func__); | ||
1473 | goto out; | ||
1474 | } | ||
1475 | } | ||
1476 | buffer_clear(&tmp); | ||
1477 | |||
1478 | buffer_append(&key->cert->extensions, exts, elen); | ||
1479 | buffer_append(&tmp, exts, elen); | ||
1480 | /* validate structure */ | ||
1481 | while (buffer_len(&tmp) != 0) { | ||
1482 | if (buffer_get_string_ptr_ret(&tmp, NULL) == NULL || | ||
1483 | buffer_get_string_ptr_ret(&tmp, NULL) == NULL) { | ||
1484 | error("%s: extension data invalid", __func__); | ||
1485 | goto out; | ||
1486 | } | ||
1487 | } | ||
1488 | buffer_clear(&tmp); | ||
1489 | |||
1490 | if ((key->cert->signature_key = key_from_blob2(sig_key, sklen, 0)) | ||
1491 | == NULL) { | ||
1492 | error("%s: Signature key invalid", __func__); | ||
1493 | goto out; | ||
1494 | } | ||
1495 | if (!key_type_is_valid_ca(key->cert->signature_key->type)) { | ||
1496 | error("%s: Invalid signature key type %s (%d)", __func__, | ||
1497 | key_type(key->cert->signature_key), | ||
1498 | key->cert->signature_key->type); | ||
1499 | goto out; | ||
1500 | } | ||
1501 | |||
1502 | switch (key_verify(key->cert->signature_key, sig, slen, | ||
1503 | buffer_ptr(&key->cert->certblob), signed_len)) { | ||
1504 | case 1: | ||
1505 | ret = 0; | ||
1506 | break; /* Good signature */ | ||
1507 | case 0: | ||
1508 | error("%s: Invalid signature on certificate", __func__); | ||
1509 | goto out; | ||
1510 | case -1: | ||
1511 | error("%s: Certificate signature verification failed", | ||
1512 | __func__); | ||
1513 | goto out; | ||
1514 | } | ||
1515 | |||
1516 | out: | ||
1517 | buffer_free(&tmp); | ||
1518 | free(principals); | ||
1519 | free(critical); | ||
1520 | free(exts); | ||
1521 | free(sig_key); | ||
1522 | free(sig); | ||
1523 | return ret; | 100 | return ret; |
1524 | } | 101 | } |
1525 | 102 | ||
1526 | static Key * | 103 | static void |
1527 | key_from_blob2(const u_char *blob, u_int blen, int allow_cert) | 104 | fatal_on_fatal_errors(int r, const char *func, int extra_fatal) |
1528 | { | 105 | { |
1529 | Buffer b; | 106 | if (r == SSH_ERR_INTERNAL_ERROR || |
1530 | int rlen, type; | 107 | r == SSH_ERR_ALLOC_FAIL || |
1531 | u_int len; | 108 | (extra_fatal != 0 && r == extra_fatal)) |
1532 | char *ktype = NULL, *curve = NULL; | 109 | fatal("%s: %s", func, ssh_err(r)); |
1533 | u_char *pk = NULL; | ||
1534 | Key *key = NULL; | ||
1535 | #ifdef OPENSSL_HAS_ECC | ||
1536 | EC_POINT *q = NULL; | ||
1537 | int nid = -1; | ||
1538 | #endif | ||
1539 | |||
1540 | #ifdef DEBUG_PK | ||
1541 | dump_base64(stderr, blob, blen); | ||
1542 | #endif | ||
1543 | buffer_init(&b); | ||
1544 | buffer_append(&b, blob, blen); | ||
1545 | if ((ktype = buffer_get_cstring_ret(&b, NULL)) == NULL) { | ||
1546 | error("key_from_blob: can't read key type"); | ||
1547 | goto out; | ||
1548 | } | ||
1549 | |||
1550 | type = key_type_from_name(ktype); | ||
1551 | #ifdef OPENSSL_HAS_ECC | ||
1552 | if (key_type_plain(type) == KEY_ECDSA) | ||
1553 | nid = key_ecdsa_nid_from_name(ktype); | ||
1554 | #endif | ||
1555 | if (!allow_cert && key_type_is_cert(type)) { | ||
1556 | error("key_from_blob: certificate not allowed in this context"); | ||
1557 | goto out; | ||
1558 | } | ||
1559 | switch (type) { | ||
1560 | case KEY_RSA_CERT: | ||
1561 | (void)buffer_get_string_ptr_ret(&b, NULL); /* Skip nonce */ | ||
1562 | /* FALLTHROUGH */ | ||
1563 | case KEY_RSA: | ||
1564 | case KEY_RSA_CERT_V00: | ||
1565 | key = key_new(type); | ||
1566 | if (buffer_get_bignum2_ret(&b, key->rsa->e) == -1 || | ||
1567 | buffer_get_bignum2_ret(&b, key->rsa->n) == -1) { | ||
1568 | error("key_from_blob: can't read rsa key"); | ||
1569 | badkey: | ||
1570 | key_free(key); | ||
1571 | key = NULL; | ||
1572 | goto out; | ||
1573 | } | ||
1574 | #ifdef DEBUG_PK | ||
1575 | RSA_print_fp(stderr, key->rsa, 8); | ||
1576 | #endif | ||
1577 | break; | ||
1578 | case KEY_DSA_CERT: | ||
1579 | (void)buffer_get_string_ptr_ret(&b, NULL); /* Skip nonce */ | ||
1580 | /* FALLTHROUGH */ | ||
1581 | case KEY_DSA: | ||
1582 | case KEY_DSA_CERT_V00: | ||
1583 | key = key_new(type); | ||
1584 | if (buffer_get_bignum2_ret(&b, key->dsa->p) == -1 || | ||
1585 | buffer_get_bignum2_ret(&b, key->dsa->q) == -1 || | ||
1586 | buffer_get_bignum2_ret(&b, key->dsa->g) == -1 || | ||
1587 | buffer_get_bignum2_ret(&b, key->dsa->pub_key) == -1) { | ||
1588 | error("key_from_blob: can't read dsa key"); | ||
1589 | goto badkey; | ||
1590 | } | ||
1591 | #ifdef DEBUG_PK | ||
1592 | DSA_print_fp(stderr, key->dsa, 8); | ||
1593 | #endif | ||
1594 | break; | ||
1595 | #ifdef OPENSSL_HAS_ECC | ||
1596 | case KEY_ECDSA_CERT: | ||
1597 | (void)buffer_get_string_ptr_ret(&b, NULL); /* Skip nonce */ | ||
1598 | /* FALLTHROUGH */ | ||
1599 | case KEY_ECDSA: | ||
1600 | key = key_new(type); | ||
1601 | key->ecdsa_nid = nid; | ||
1602 | if ((curve = buffer_get_string_ret(&b, NULL)) == NULL) { | ||
1603 | error("key_from_blob: can't read ecdsa curve"); | ||
1604 | goto badkey; | ||
1605 | } | ||
1606 | if (key->ecdsa_nid != key_curve_name_to_nid(curve)) { | ||
1607 | error("key_from_blob: ecdsa curve doesn't match type"); | ||
1608 | goto badkey; | ||
1609 | } | ||
1610 | if (key->ecdsa != NULL) | ||
1611 | EC_KEY_free(key->ecdsa); | ||
1612 | if ((key->ecdsa = EC_KEY_new_by_curve_name(key->ecdsa_nid)) | ||
1613 | == NULL) | ||
1614 | fatal("key_from_blob: EC_KEY_new_by_curve_name failed"); | ||
1615 | if ((q = EC_POINT_new(EC_KEY_get0_group(key->ecdsa))) == NULL) | ||
1616 | fatal("key_from_blob: EC_POINT_new failed"); | ||
1617 | if (buffer_get_ecpoint_ret(&b, EC_KEY_get0_group(key->ecdsa), | ||
1618 | q) == -1) { | ||
1619 | error("key_from_blob: can't read ecdsa key point"); | ||
1620 | goto badkey; | ||
1621 | } | ||
1622 | if (key_ec_validate_public(EC_KEY_get0_group(key->ecdsa), | ||
1623 | q) != 0) | ||
1624 | goto badkey; | ||
1625 | if (EC_KEY_set_public_key(key->ecdsa, q) != 1) | ||
1626 | fatal("key_from_blob: EC_KEY_set_public_key failed"); | ||
1627 | #ifdef DEBUG_PK | ||
1628 | key_dump_ec_point(EC_KEY_get0_group(key->ecdsa), q); | ||
1629 | #endif | ||
1630 | break; | ||
1631 | #endif /* OPENSSL_HAS_ECC */ | ||
1632 | case KEY_ED25519_CERT: | ||
1633 | (void)buffer_get_string_ptr_ret(&b, NULL); /* Skip nonce */ | ||
1634 | /* FALLTHROUGH */ | ||
1635 | case KEY_ED25519: | ||
1636 | if ((pk = buffer_get_string_ret(&b, &len)) == NULL) { | ||
1637 | error("key_from_blob: can't read ed25519 key"); | ||
1638 | goto badkey; | ||
1639 | } | ||
1640 | if (len != ED25519_PK_SZ) { | ||
1641 | error("key_from_blob: ed25519 len %d != %d", | ||
1642 | len, ED25519_PK_SZ); | ||
1643 | goto badkey; | ||
1644 | } | ||
1645 | key = key_new(type); | ||
1646 | key->ed25519_pk = pk; | ||
1647 | pk = NULL; | ||
1648 | break; | ||
1649 | case KEY_UNSPEC: | ||
1650 | key = key_new(type); | ||
1651 | break; | ||
1652 | default: | ||
1653 | error("key_from_blob: cannot handle type %s", ktype); | ||
1654 | goto out; | ||
1655 | } | ||
1656 | if (key_is_cert(key) && cert_parse(&b, key, blob, blen) == -1) { | ||
1657 | error("key_from_blob: can't parse cert data"); | ||
1658 | goto badkey; | ||
1659 | } | ||
1660 | rlen = buffer_len(&b); | ||
1661 | if (key != NULL && rlen != 0) | ||
1662 | error("key_from_blob: remaining bytes in key blob %d", rlen); | ||
1663 | out: | ||
1664 | free(ktype); | ||
1665 | free(curve); | ||
1666 | free(pk); | ||
1667 | #ifdef OPENSSL_HAS_ECC | ||
1668 | if (q != NULL) | ||
1669 | EC_POINT_free(q); | ||
1670 | #endif | ||
1671 | buffer_free(&b); | ||
1672 | return key; | ||
1673 | } | 110 | } |
1674 | 111 | ||
1675 | Key * | 112 | Key * |
1676 | key_from_blob(const u_char *blob, u_int blen) | 113 | key_from_blob(const u_char *blob, u_int blen) |
1677 | { | 114 | { |
1678 | return key_from_blob2(blob, blen, 1); | 115 | int r; |
116 | Key *ret = NULL; | ||
117 | |||
118 | if ((r = sshkey_from_blob(blob, blen, &ret)) != 0) { | ||
119 | fatal_on_fatal_errors(r, __func__, 0); | ||
120 | error("%s: %s", __func__, ssh_err(r)); | ||
121 | return NULL; | ||
122 | } | ||
123 | return ret; | ||
1679 | } | 124 | } |
1680 | 125 | ||
1681 | static int | 126 | int |
1682 | to_blob(const Key *key, u_char **blobp, u_int *lenp, int force_plain) | 127 | key_to_blob(const Key *key, u_char **blobp, u_int *lenp) |
1683 | { | 128 | { |
1684 | Buffer b; | 129 | u_char *blob; |
1685 | int len, type; | 130 | size_t blen; |
131 | int r; | ||
1686 | 132 | ||
1687 | if (blobp != NULL) | 133 | if (blobp != NULL) |
1688 | *blobp = NULL; | 134 | *blobp = NULL; |
1689 | if (lenp != NULL) | 135 | if (lenp != NULL) |
1690 | *lenp = 0; | 136 | *lenp = 0; |
1691 | if (key == NULL) { | 137 | if ((r = sshkey_to_blob(key, &blob, &blen)) != 0) { |
1692 | error("key_to_blob: key == NULL"); | 138 | fatal_on_fatal_errors(r, __func__, 0); |
1693 | return 0; | 139 | error("%s: %s", __func__, ssh_err(r)); |
1694 | } | ||
1695 | buffer_init(&b); | ||
1696 | type = force_plain ? key_type_plain(key->type) : key->type; | ||
1697 | switch (type) { | ||
1698 | case KEY_DSA_CERT_V00: | ||
1699 | case KEY_RSA_CERT_V00: | ||
1700 | case KEY_DSA_CERT: | ||
1701 | case KEY_ECDSA_CERT: | ||
1702 | case KEY_RSA_CERT: | ||
1703 | case KEY_ED25519_CERT: | ||
1704 | /* Use the existing blob */ | ||
1705 | buffer_append(&b, buffer_ptr(&key->cert->certblob), | ||
1706 | buffer_len(&key->cert->certblob)); | ||
1707 | break; | ||
1708 | case KEY_DSA: | ||
1709 | buffer_put_cstring(&b, | ||
1710 | key_ssh_name_from_type_nid(type, key->ecdsa_nid)); | ||
1711 | buffer_put_bignum2(&b, key->dsa->p); | ||
1712 | buffer_put_bignum2(&b, key->dsa->q); | ||
1713 | buffer_put_bignum2(&b, key->dsa->g); | ||
1714 | buffer_put_bignum2(&b, key->dsa->pub_key); | ||
1715 | break; | ||
1716 | #ifdef OPENSSL_HAS_ECC | ||
1717 | case KEY_ECDSA: | ||
1718 | buffer_put_cstring(&b, | ||
1719 | key_ssh_name_from_type_nid(type, key->ecdsa_nid)); | ||
1720 | buffer_put_cstring(&b, key_curve_nid_to_name(key->ecdsa_nid)); | ||
1721 | buffer_put_ecpoint(&b, EC_KEY_get0_group(key->ecdsa), | ||
1722 | EC_KEY_get0_public_key(key->ecdsa)); | ||
1723 | break; | ||
1724 | #endif | ||
1725 | case KEY_RSA: | ||
1726 | buffer_put_cstring(&b, | ||
1727 | key_ssh_name_from_type_nid(type, key->ecdsa_nid)); | ||
1728 | buffer_put_bignum2(&b, key->rsa->e); | ||
1729 | buffer_put_bignum2(&b, key->rsa->n); | ||
1730 | break; | ||
1731 | case KEY_ED25519: | ||
1732 | buffer_put_cstring(&b, | ||
1733 | key_ssh_name_from_type_nid(type, key->ecdsa_nid)); | ||
1734 | buffer_put_string(&b, key->ed25519_pk, ED25519_PK_SZ); | ||
1735 | break; | ||
1736 | default: | ||
1737 | error("key_to_blob: unsupported key type %d", key->type); | ||
1738 | buffer_free(&b); | ||
1739 | return 0; | 140 | return 0; |
1740 | } | 141 | } |
1741 | len = buffer_len(&b); | 142 | if (blen > INT_MAX) |
143 | fatal("%s: giant len %zu", __func__, blen); | ||
144 | if (blobp != NULL) | ||
145 | *blobp = blob; | ||
1742 | if (lenp != NULL) | 146 | if (lenp != NULL) |
1743 | *lenp = len; | 147 | *lenp = blen; |
1744 | if (blobp != NULL) { | 148 | return blen; |
1745 | *blobp = xmalloc(len); | ||
1746 | memcpy(*blobp, buffer_ptr(&b), len); | ||
1747 | } | ||
1748 | explicit_bzero(buffer_ptr(&b), len); | ||
1749 | buffer_free(&b); | ||
1750 | return len; | ||
1751 | } | ||
1752 | |||
1753 | int | ||
1754 | key_to_blob(const Key *key, u_char **blobp, u_int *lenp) | ||
1755 | { | ||
1756 | return to_blob(key, blobp, lenp, 0); | ||
1757 | } | 149 | } |
1758 | 150 | ||
1759 | int | 151 | int |
1760 | key_sign( | 152 | key_sign(const Key *key, u_char **sigp, u_int *lenp, |
1761 | const Key *key, | ||
1762 | u_char **sigp, u_int *lenp, | ||
1763 | const u_char *data, u_int datalen) | 153 | const u_char *data, u_int datalen) |
1764 | { | 154 | { |
1765 | switch (key->type) { | 155 | int r; |
1766 | case KEY_DSA_CERT_V00: | 156 | u_char *sig; |
1767 | case KEY_DSA_CERT: | 157 | size_t siglen; |
1768 | case KEY_DSA: | 158 | |
1769 | return ssh_dss_sign(key, sigp, lenp, data, datalen); | 159 | if (sigp != NULL) |
1770 | #ifdef OPENSSL_HAS_ECC | 160 | *sigp = NULL; |
1771 | case KEY_ECDSA_CERT: | 161 | if (lenp != NULL) |
1772 | case KEY_ECDSA: | 162 | *lenp = 0; |
1773 | return ssh_ecdsa_sign(key, sigp, lenp, data, datalen); | 163 | if ((r = sshkey_sign(key, &sig, &siglen, |
1774 | #endif | 164 | data, datalen, datafellows)) != 0) { |
1775 | case KEY_RSA_CERT_V00: | 165 | fatal_on_fatal_errors(r, __func__, 0); |
1776 | case KEY_RSA_CERT: | 166 | error("%s: %s", __func__, ssh_err(r)); |
1777 | case KEY_RSA: | ||
1778 | return ssh_rsa_sign(key, sigp, lenp, data, datalen); | ||
1779 | case KEY_ED25519: | ||
1780 | case KEY_ED25519_CERT: | ||
1781 | return ssh_ed25519_sign(key, sigp, lenp, data, datalen); | ||
1782 | default: | ||
1783 | error("key_sign: invalid key type %d", key->type); | ||
1784 | return -1; | 167 | return -1; |
1785 | } | 168 | } |
169 | if (siglen > INT_MAX) | ||
170 | fatal("%s: giant len %zu", __func__, siglen); | ||
171 | if (sigp != NULL) | ||
172 | *sigp = sig; | ||
173 | if (lenp != NULL) | ||
174 | *lenp = siglen; | ||
175 | return 0; | ||
1786 | } | 176 | } |
1787 | 177 | ||
1788 | /* | ||
1789 | * key_verify returns 1 for a correct signature, 0 for an incorrect signature | ||
1790 | * and -1 on error. | ||
1791 | */ | ||
1792 | int | 178 | int |
1793 | key_verify( | 179 | key_verify(const Key *key, const u_char *signature, u_int signaturelen, |
1794 | const Key *key, | ||
1795 | const u_char *signature, u_int signaturelen, | ||
1796 | const u_char *data, u_int datalen) | 180 | const u_char *data, u_int datalen) |
1797 | { | 181 | { |
1798 | if (signaturelen == 0) | 182 | int r; |
1799 | return -1; | ||
1800 | 183 | ||
1801 | switch (key->type) { | 184 | if ((r = sshkey_verify(key, signature, signaturelen, |
1802 | case KEY_DSA_CERT_V00: | 185 | data, datalen, datafellows)) != 0) { |
1803 | case KEY_DSA_CERT: | 186 | fatal_on_fatal_errors(r, __func__, 0); |
1804 | case KEY_DSA: | 187 | error("%s: %s", __func__, ssh_err(r)); |
1805 | return ssh_dss_verify(key, signature, signaturelen, data, datalen); | 188 | return r == SSH_ERR_SIGNATURE_INVALID ? 0 : -1; |
1806 | #ifdef OPENSSL_HAS_ECC | ||
1807 | case KEY_ECDSA_CERT: | ||
1808 | case KEY_ECDSA: | ||
1809 | return ssh_ecdsa_verify(key, signature, signaturelen, data, datalen); | ||
1810 | #endif | ||
1811 | case KEY_RSA_CERT_V00: | ||
1812 | case KEY_RSA_CERT: | ||
1813 | case KEY_RSA: | ||
1814 | return ssh_rsa_verify(key, signature, signaturelen, data, datalen); | ||
1815 | case KEY_ED25519: | ||
1816 | case KEY_ED25519_CERT: | ||
1817 | return ssh_ed25519_verify(key, signature, signaturelen, data, datalen); | ||
1818 | default: | ||
1819 | error("key_verify: invalid key type %d", key->type); | ||
1820 | return -1; | ||
1821 | } | 189 | } |
190 | return 1; | ||
1822 | } | 191 | } |
1823 | 192 | ||
1824 | /* Converts a private to a public key */ | ||
1825 | Key * | 193 | Key * |
1826 | key_demote(const Key *k) | 194 | key_demote(const Key *k) |
1827 | { | 195 | { |
1828 | Key *pk; | 196 | int r; |
1829 | 197 | Key *ret = NULL; | |
1830 | pk = xcalloc(1, sizeof(*pk)); | ||
1831 | pk->type = k->type; | ||
1832 | pk->flags = k->flags; | ||
1833 | pk->ecdsa_nid = k->ecdsa_nid; | ||
1834 | pk->dsa = NULL; | ||
1835 | pk->ecdsa = NULL; | ||
1836 | pk->rsa = NULL; | ||
1837 | pk->ed25519_pk = NULL; | ||
1838 | pk->ed25519_sk = NULL; | ||
1839 | |||
1840 | switch (k->type) { | ||
1841 | case KEY_RSA_CERT_V00: | ||
1842 | case KEY_RSA_CERT: | ||
1843 | key_cert_copy(k, pk); | ||
1844 | /* FALLTHROUGH */ | ||
1845 | case KEY_RSA1: | ||
1846 | case KEY_RSA: | ||
1847 | if ((pk->rsa = RSA_new()) == NULL) | ||
1848 | fatal("key_demote: RSA_new failed"); | ||
1849 | if ((pk->rsa->e = BN_dup(k->rsa->e)) == NULL) | ||
1850 | fatal("key_demote: BN_dup failed"); | ||
1851 | if ((pk->rsa->n = BN_dup(k->rsa->n)) == NULL) | ||
1852 | fatal("key_demote: BN_dup failed"); | ||
1853 | break; | ||
1854 | case KEY_DSA_CERT_V00: | ||
1855 | case KEY_DSA_CERT: | ||
1856 | key_cert_copy(k, pk); | ||
1857 | /* FALLTHROUGH */ | ||
1858 | case KEY_DSA: | ||
1859 | if ((pk->dsa = DSA_new()) == NULL) | ||
1860 | fatal("key_demote: DSA_new failed"); | ||
1861 | if ((pk->dsa->p = BN_dup(k->dsa->p)) == NULL) | ||
1862 | fatal("key_demote: BN_dup failed"); | ||
1863 | if ((pk->dsa->q = BN_dup(k->dsa->q)) == NULL) | ||
1864 | fatal("key_demote: BN_dup failed"); | ||
1865 | if ((pk->dsa->g = BN_dup(k->dsa->g)) == NULL) | ||
1866 | fatal("key_demote: BN_dup failed"); | ||
1867 | if ((pk->dsa->pub_key = BN_dup(k->dsa->pub_key)) == NULL) | ||
1868 | fatal("key_demote: BN_dup failed"); | ||
1869 | break; | ||
1870 | #ifdef OPENSSL_HAS_ECC | ||
1871 | case KEY_ECDSA_CERT: | ||
1872 | key_cert_copy(k, pk); | ||
1873 | /* FALLTHROUGH */ | ||
1874 | case KEY_ECDSA: | ||
1875 | if ((pk->ecdsa = EC_KEY_new_by_curve_name(pk->ecdsa_nid)) == NULL) | ||
1876 | fatal("key_demote: EC_KEY_new_by_curve_name failed"); | ||
1877 | if (EC_KEY_set_public_key(pk->ecdsa, | ||
1878 | EC_KEY_get0_public_key(k->ecdsa)) != 1) | ||
1879 | fatal("key_demote: EC_KEY_set_public_key failed"); | ||
1880 | break; | ||
1881 | #endif | ||
1882 | case KEY_ED25519_CERT: | ||
1883 | key_cert_copy(k, pk); | ||
1884 | /* FALLTHROUGH */ | ||
1885 | case KEY_ED25519: | ||
1886 | if (k->ed25519_pk != NULL) { | ||
1887 | pk->ed25519_pk = xmalloc(ED25519_PK_SZ); | ||
1888 | memcpy(pk->ed25519_pk, k->ed25519_pk, ED25519_PK_SZ); | ||
1889 | } | ||
1890 | break; | ||
1891 | default: | ||
1892 | fatal("key_demote: bad key type %d", k->type); | ||
1893 | break; | ||
1894 | } | ||
1895 | |||
1896 | return (pk); | ||
1897 | } | ||
1898 | 198 | ||
1899 | int | 199 | if ((r = sshkey_demote(k, &ret)) != 0) |
1900 | key_is_cert(const Key *k) | 200 | fatal("%s: %s", __func__, ssh_err(r)); |
1901 | { | 201 | return ret; |
1902 | if (k == NULL) | ||
1903 | return 0; | ||
1904 | return key_type_is_cert(k->type); | ||
1905 | } | ||
1906 | |||
1907 | /* Return the cert-less equivalent to a certified key type */ | ||
1908 | int | ||
1909 | key_type_plain(int type) | ||
1910 | { | ||
1911 | switch (type) { | ||
1912 | case KEY_RSA_CERT_V00: | ||
1913 | case KEY_RSA_CERT: | ||
1914 | return KEY_RSA; | ||
1915 | case KEY_DSA_CERT_V00: | ||
1916 | case KEY_DSA_CERT: | ||
1917 | return KEY_DSA; | ||
1918 | case KEY_ECDSA_CERT: | ||
1919 | return KEY_ECDSA; | ||
1920 | case KEY_ED25519_CERT: | ||
1921 | return KEY_ED25519; | ||
1922 | default: | ||
1923 | return type; | ||
1924 | } | ||
1925 | } | 202 | } |
1926 | 203 | ||
1927 | /* Convert a plain key to their _CERT equivalent */ | ||
1928 | int | 204 | int |
1929 | key_to_certified(Key *k, int legacy) | 205 | key_to_certified(Key *k, int legacy) |
1930 | { | 206 | { |
1931 | switch (k->type) { | 207 | int r; |
1932 | case KEY_RSA: | 208 | |
1933 | k->cert = cert_new(); | 209 | if ((r = sshkey_to_certified(k, legacy)) != 0) { |
1934 | k->type = legacy ? KEY_RSA_CERT_V00 : KEY_RSA_CERT; | 210 | fatal_on_fatal_errors(r, __func__, 0); |
1935 | return 0; | 211 | error("%s: %s", __func__, ssh_err(r)); |
1936 | case KEY_DSA: | ||
1937 | k->cert = cert_new(); | ||
1938 | k->type = legacy ? KEY_DSA_CERT_V00 : KEY_DSA_CERT; | ||
1939 | return 0; | ||
1940 | case KEY_ECDSA: | ||
1941 | if (legacy) | ||
1942 | fatal("%s: legacy ECDSA certificates are not supported", | ||
1943 | __func__); | ||
1944 | k->cert = cert_new(); | ||
1945 | k->type = KEY_ECDSA_CERT; | ||
1946 | return 0; | ||
1947 | case KEY_ED25519: | ||
1948 | if (legacy) | ||
1949 | fatal("%s: legacy ED25519 certificates are not " | ||
1950 | "supported", __func__); | ||
1951 | k->cert = cert_new(); | ||
1952 | k->type = KEY_ED25519_CERT; | ||
1953 | return 0; | ||
1954 | default: | ||
1955 | error("%s: key has incorrect type %s", __func__, key_type(k)); | ||
1956 | return -1; | 212 | return -1; |
1957 | } | 213 | } |
214 | return 0; | ||
1958 | } | 215 | } |
1959 | 216 | ||
1960 | /* Convert a certificate to its raw key equivalent */ | ||
1961 | int | 217 | int |
1962 | key_drop_cert(Key *k) | 218 | key_drop_cert(Key *k) |
1963 | { | 219 | { |
1964 | if (!key_type_is_cert(k->type)) { | 220 | int r; |
1965 | error("%s: key has incorrect type %s", __func__, key_type(k)); | 221 | |
222 | if ((r = sshkey_drop_cert(k)) != 0) { | ||
223 | fatal_on_fatal_errors(r, __func__, 0); | ||
224 | error("%s: %s", __func__, ssh_err(r)); | ||
1966 | return -1; | 225 | return -1; |
1967 | } | 226 | } |
1968 | cert_free(k->cert); | ||
1969 | k->cert = NULL; | ||
1970 | k->type = key_type_plain(k->type); | ||
1971 | return 0; | 227 | return 0; |
1972 | } | 228 | } |
1973 | 229 | ||
1974 | /* Sign a certified key, (re-)generating the signed certblob. */ | ||
1975 | int | 230 | int |
1976 | key_certify(Key *k, Key *ca) | 231 | key_certify(Key *k, Key *ca) |
1977 | { | 232 | { |
1978 | Buffer principals; | 233 | int r; |
1979 | u_char *ca_blob, *sig_blob, nonce[32]; | ||
1980 | u_int i, ca_len, sig_len; | ||
1981 | |||
1982 | if (k->cert == NULL) { | ||
1983 | error("%s: key lacks cert info", __func__); | ||
1984 | return -1; | ||
1985 | } | ||
1986 | |||
1987 | if (!key_is_cert(k)) { | ||
1988 | error("%s: certificate has unknown type %d", __func__, | ||
1989 | k->cert->type); | ||
1990 | return -1; | ||
1991 | } | ||
1992 | |||
1993 | if (!key_type_is_valid_ca(ca->type)) { | ||
1994 | error("%s: CA key has unsupported type %s", __func__, | ||
1995 | key_type(ca)); | ||
1996 | return -1; | ||
1997 | } | ||
1998 | |||
1999 | key_to_blob(ca, &ca_blob, &ca_len); | ||
2000 | |||
2001 | buffer_clear(&k->cert->certblob); | ||
2002 | buffer_put_cstring(&k->cert->certblob, key_ssh_name(k)); | ||
2003 | |||
2004 | /* -v01 certs put nonce first */ | ||
2005 | arc4random_buf(&nonce, sizeof(nonce)); | ||
2006 | if (!key_cert_is_legacy(k)) | ||
2007 | buffer_put_string(&k->cert->certblob, nonce, sizeof(nonce)); | ||
2008 | |||
2009 | /* XXX this substantially duplicates to_blob(); refactor */ | ||
2010 | switch (k->type) { | ||
2011 | case KEY_DSA_CERT_V00: | ||
2012 | case KEY_DSA_CERT: | ||
2013 | buffer_put_bignum2(&k->cert->certblob, k->dsa->p); | ||
2014 | buffer_put_bignum2(&k->cert->certblob, k->dsa->q); | ||
2015 | buffer_put_bignum2(&k->cert->certblob, k->dsa->g); | ||
2016 | buffer_put_bignum2(&k->cert->certblob, k->dsa->pub_key); | ||
2017 | break; | ||
2018 | #ifdef OPENSSL_HAS_ECC | ||
2019 | case KEY_ECDSA_CERT: | ||
2020 | buffer_put_cstring(&k->cert->certblob, | ||
2021 | key_curve_nid_to_name(k->ecdsa_nid)); | ||
2022 | buffer_put_ecpoint(&k->cert->certblob, | ||
2023 | EC_KEY_get0_group(k->ecdsa), | ||
2024 | EC_KEY_get0_public_key(k->ecdsa)); | ||
2025 | break; | ||
2026 | #endif | ||
2027 | case KEY_RSA_CERT_V00: | ||
2028 | case KEY_RSA_CERT: | ||
2029 | buffer_put_bignum2(&k->cert->certblob, k->rsa->e); | ||
2030 | buffer_put_bignum2(&k->cert->certblob, k->rsa->n); | ||
2031 | break; | ||
2032 | case KEY_ED25519_CERT: | ||
2033 | buffer_put_string(&k->cert->certblob, | ||
2034 | k->ed25519_pk, ED25519_PK_SZ); | ||
2035 | break; | ||
2036 | default: | ||
2037 | error("%s: key has incorrect type %s", __func__, key_type(k)); | ||
2038 | buffer_clear(&k->cert->certblob); | ||
2039 | free(ca_blob); | ||
2040 | return -1; | ||
2041 | } | ||
2042 | |||
2043 | /* -v01 certs have a serial number next */ | ||
2044 | if (!key_cert_is_legacy(k)) | ||
2045 | buffer_put_int64(&k->cert->certblob, k->cert->serial); | ||
2046 | |||
2047 | buffer_put_int(&k->cert->certblob, k->cert->type); | ||
2048 | buffer_put_cstring(&k->cert->certblob, k->cert->key_id); | ||
2049 | |||
2050 | buffer_init(&principals); | ||
2051 | for (i = 0; i < k->cert->nprincipals; i++) | ||
2052 | buffer_put_cstring(&principals, k->cert->principals[i]); | ||
2053 | buffer_put_string(&k->cert->certblob, buffer_ptr(&principals), | ||
2054 | buffer_len(&principals)); | ||
2055 | buffer_free(&principals); | ||
2056 | |||
2057 | buffer_put_int64(&k->cert->certblob, k->cert->valid_after); | ||
2058 | buffer_put_int64(&k->cert->certblob, k->cert->valid_before); | ||
2059 | buffer_put_string(&k->cert->certblob, | ||
2060 | buffer_ptr(&k->cert->critical), buffer_len(&k->cert->critical)); | ||
2061 | |||
2062 | /* -v01 certs have non-critical options here */ | ||
2063 | if (!key_cert_is_legacy(k)) { | ||
2064 | buffer_put_string(&k->cert->certblob, | ||
2065 | buffer_ptr(&k->cert->extensions), | ||
2066 | buffer_len(&k->cert->extensions)); | ||
2067 | } | ||
2068 | |||
2069 | /* -v00 certs put the nonce at the end */ | ||
2070 | if (key_cert_is_legacy(k)) | ||
2071 | buffer_put_string(&k->cert->certblob, nonce, sizeof(nonce)); | ||
2072 | |||
2073 | buffer_put_string(&k->cert->certblob, NULL, 0); /* reserved */ | ||
2074 | buffer_put_string(&k->cert->certblob, ca_blob, ca_len); | ||
2075 | free(ca_blob); | ||
2076 | 234 | ||
2077 | /* Sign the whole mess */ | 235 | if ((r = sshkey_certify(k, ca)) != 0) { |
2078 | if (key_sign(ca, &sig_blob, &sig_len, buffer_ptr(&k->cert->certblob), | 236 | fatal_on_fatal_errors(r, __func__, 0); |
2079 | buffer_len(&k->cert->certblob)) != 0) { | 237 | error("%s: %s", __func__, ssh_err(r)); |
2080 | error("%s: signature operation failed", __func__); | ||
2081 | buffer_clear(&k->cert->certblob); | ||
2082 | return -1; | 238 | return -1; |
2083 | } | 239 | } |
2084 | /* Append signature and we are done */ | ||
2085 | buffer_put_string(&k->cert->certblob, sig_blob, sig_len); | ||
2086 | free(sig_blob); | ||
2087 | |||
2088 | return 0; | 240 | return 0; |
2089 | } | 241 | } |
2090 | 242 | ||
@@ -2092,535 +244,236 @@ int | |||
2092 | key_cert_check_authority(const Key *k, int want_host, int require_principal, | 244 | key_cert_check_authority(const Key *k, int want_host, int require_principal, |
2093 | const char *name, const char **reason) | 245 | const char *name, const char **reason) |
2094 | { | 246 | { |
2095 | u_int i, principal_matches; | 247 | int r; |
2096 | time_t now = time(NULL); | 248 | |
2097 | 249 | if ((r = sshkey_cert_check_authority(k, want_host, require_principal, | |
2098 | if (want_host) { | 250 | name, reason)) != 0) { |
2099 | if (k->cert->type != SSH2_CERT_TYPE_HOST) { | 251 | fatal_on_fatal_errors(r, __func__, 0); |
2100 | *reason = "Certificate invalid: not a host certificate"; | 252 | error("%s: %s", __func__, ssh_err(r)); |
2101 | return -1; | ||
2102 | } | ||
2103 | } else { | ||
2104 | if (k->cert->type != SSH2_CERT_TYPE_USER) { | ||
2105 | *reason = "Certificate invalid: not a user certificate"; | ||
2106 | return -1; | ||
2107 | } | ||
2108 | } | ||
2109 | if (now < 0) { | ||
2110 | error("%s: system clock lies before epoch", __func__); | ||
2111 | *reason = "Certificate invalid: not yet valid"; | ||
2112 | return -1; | ||
2113 | } | ||
2114 | if ((u_int64_t)now < k->cert->valid_after) { | ||
2115 | *reason = "Certificate invalid: not yet valid"; | ||
2116 | return -1; | ||
2117 | } | ||
2118 | if ((u_int64_t)now >= k->cert->valid_before) { | ||
2119 | *reason = "Certificate invalid: expired"; | ||
2120 | return -1; | 253 | return -1; |
2121 | } | 254 | } |
2122 | if (k->cert->nprincipals == 0) { | ||
2123 | if (require_principal) { | ||
2124 | *reason = "Certificate lacks principal list"; | ||
2125 | return -1; | ||
2126 | } | ||
2127 | } else if (name != NULL) { | ||
2128 | principal_matches = 0; | ||
2129 | for (i = 0; i < k->cert->nprincipals; i++) { | ||
2130 | if (strcmp(name, k->cert->principals[i]) == 0) { | ||
2131 | principal_matches = 1; | ||
2132 | break; | ||
2133 | } | ||
2134 | } | ||
2135 | if (!principal_matches) { | ||
2136 | *reason = "Certificate invalid: name is not a listed " | ||
2137 | "principal"; | ||
2138 | return -1; | ||
2139 | } | ||
2140 | } | ||
2141 | return 0; | 255 | return 0; |
2142 | } | 256 | } |
2143 | 257 | ||
258 | #if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) | ||
2144 | int | 259 | int |
2145 | key_cert_is_legacy(const Key *k) | 260 | key_ec_validate_public(const EC_GROUP *group, const EC_POINT *public) |
2146 | { | 261 | { |
2147 | switch (k->type) { | 262 | int r; |
2148 | case KEY_DSA_CERT_V00: | 263 | |
2149 | case KEY_RSA_CERT_V00: | 264 | if ((r = sshkey_ec_validate_public(group, public)) != 0) { |
2150 | return 1; | 265 | fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR); |
2151 | default: | 266 | error("%s: %s", __func__, ssh_err(r)); |
2152 | return 0; | 267 | return -1; |
2153 | } | 268 | } |
269 | return 0; | ||
2154 | } | 270 | } |
2155 | 271 | ||
2156 | /* XXX: these are really begging for a table-driven approach */ | ||
2157 | int | 272 | int |
2158 | key_curve_name_to_nid(const char *name) | 273 | key_ec_validate_private(const EC_KEY *key) |
2159 | { | 274 | { |
2160 | #ifdef OPENSSL_HAS_ECC | 275 | int r; |
2161 | if (strcmp(name, "nistp256") == 0) | 276 | |
2162 | return NID_X9_62_prime256v1; | 277 | if ((r = sshkey_ec_validate_private(key)) != 0) { |
2163 | else if (strcmp(name, "nistp384") == 0) | 278 | fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR); |
2164 | return NID_secp384r1; | 279 | error("%s: %s", __func__, ssh_err(r)); |
2165 | # ifdef OPENSSL_HAS_NISTP521 | 280 | return -1; |
2166 | else if (strcmp(name, "nistp521") == 0) | 281 | } |
2167 | return NID_secp521r1; | 282 | return 0; |
2168 | # endif | ||
2169 | #endif | ||
2170 | |||
2171 | debug("%s: unsupported EC curve name \"%.100s\"", __func__, name); | ||
2172 | return -1; | ||
2173 | } | 283 | } |
284 | #endif /* WITH_OPENSSL */ | ||
2174 | 285 | ||
2175 | u_int | 286 | void |
2176 | key_curve_nid_to_bits(int nid) | 287 | key_private_serialize(const Key *key, struct sshbuf *b) |
2177 | { | 288 | { |
2178 | switch (nid) { | 289 | int r; |
2179 | #ifdef OPENSSL_HAS_ECC | 290 | |
2180 | case NID_X9_62_prime256v1: | 291 | if ((r = sshkey_private_serialize(key, b)) != 0) |
2181 | return 256; | 292 | fatal("%s: %s", __func__, ssh_err(r)); |
2182 | case NID_secp384r1: | ||
2183 | return 384; | ||
2184 | # ifdef OPENSSL_HAS_NISTP521 | ||
2185 | case NID_secp521r1: | ||
2186 | return 521; | ||
2187 | # endif | ||
2188 | #endif | ||
2189 | default: | ||
2190 | error("%s: unsupported EC curve nid %d", __func__, nid); | ||
2191 | return 0; | ||
2192 | } | ||
2193 | } | 293 | } |
2194 | 294 | ||
2195 | const char * | 295 | Key * |
2196 | key_curve_nid_to_name(int nid) | 296 | key_private_deserialize(struct sshbuf *blob) |
2197 | { | 297 | { |
2198 | #ifdef OPENSSL_HAS_ECC | 298 | int r; |
2199 | if (nid == NID_X9_62_prime256v1) | 299 | Key *ret = NULL; |
2200 | return "nistp256"; | 300 | |
2201 | else if (nid == NID_secp384r1) | 301 | if ((r = sshkey_private_deserialize(blob, &ret)) != 0) { |
2202 | return "nistp384"; | 302 | fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR); |
2203 | # ifdef OPENSSL_HAS_NISTP521 | 303 | error("%s: %s", __func__, ssh_err(r)); |
2204 | else if (nid == NID_secp521r1) | 304 | return NULL; |
2205 | return "nistp521"; | 305 | } |
2206 | # endif | 306 | return ret; |
2207 | #endif | ||
2208 | error("%s: unsupported EC curve nid %d", __func__, nid); | ||
2209 | return NULL; | ||
2210 | } | 307 | } |
2211 | 308 | ||
2212 | #ifdef OPENSSL_HAS_ECC | 309 | /* authfile.c */ |
310 | |||
2213 | int | 311 | int |
2214 | key_ec_nid_to_hash_alg(int nid) | 312 | key_save_private(Key *key, const char *filename, const char *passphrase, |
313 | const char *comment, int force_new_format, const char *new_format_cipher, | ||
314 | int new_format_rounds) | ||
2215 | { | 315 | { |
2216 | int kbits = key_curve_nid_to_bits(nid); | 316 | int r; |
2217 | 317 | ||
2218 | if (kbits == 0) | 318 | if ((r = sshkey_save_private(key, filename, passphrase, comment, |
2219 | fatal("%s: invalid nid %d", __func__, nid); | 319 | force_new_format, new_format_cipher, new_format_rounds)) != 0) { |
2220 | /* RFC5656 section 6.2.1 */ | 320 | fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR); |
2221 | if (kbits <= 256) | 321 | error("%s: %s", __func__, ssh_err(r)); |
2222 | return SSH_DIGEST_SHA256; | 322 | return 0; |
2223 | else if (kbits <= 384) | 323 | } |
2224 | return SSH_DIGEST_SHA384; | 324 | return 1; |
2225 | else | ||
2226 | return SSH_DIGEST_SHA512; | ||
2227 | } | 325 | } |
2228 | 326 | ||
2229 | int | 327 | int |
2230 | key_ec_validate_public(const EC_GROUP *group, const EC_POINT *public) | 328 | key_load_file(int fd, const char *filename, struct sshbuf *blob) |
2231 | { | 329 | { |
2232 | BN_CTX *bnctx; | 330 | int r; |
2233 | EC_POINT *nq = NULL; | ||
2234 | BIGNUM *order, *x, *y, *tmp; | ||
2235 | int ret = -1; | ||
2236 | |||
2237 | if ((bnctx = BN_CTX_new()) == NULL) | ||
2238 | fatal("%s: BN_CTX_new failed", __func__); | ||
2239 | BN_CTX_start(bnctx); | ||
2240 | |||
2241 | /* | ||
2242 | * We shouldn't ever hit this case because bignum_get_ecpoint() | ||
2243 | * refuses to load GF2m points. | ||
2244 | */ | ||
2245 | if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) != | ||
2246 | NID_X9_62_prime_field) { | ||
2247 | error("%s: group is not a prime field", __func__); | ||
2248 | goto out; | ||
2249 | } | ||
2250 | 331 | ||
2251 | /* Q != infinity */ | 332 | if ((r = sshkey_load_file(fd, filename, blob)) != 0) { |
2252 | if (EC_POINT_is_at_infinity(group, public)) { | 333 | fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR); |
2253 | error("%s: received degenerate public key (infinity)", | 334 | error("%s: %s", __func__, ssh_err(r)); |
2254 | __func__); | 335 | return 0; |
2255 | goto out; | ||
2256 | } | 336 | } |
337 | return 1; | ||
338 | } | ||
2257 | 339 | ||
2258 | if ((x = BN_CTX_get(bnctx)) == NULL || | 340 | Key * |
2259 | (y = BN_CTX_get(bnctx)) == NULL || | 341 | key_load_cert(const char *filename) |
2260 | (order = BN_CTX_get(bnctx)) == NULL || | 342 | { |
2261 | (tmp = BN_CTX_get(bnctx)) == NULL) | 343 | int r; |
2262 | fatal("%s: BN_CTX_get failed", __func__); | 344 | Key *ret = NULL; |
2263 | 345 | ||
2264 | /* log2(x) > log2(order)/2, log2(y) > log2(order)/2 */ | 346 | if ((r = sshkey_load_cert(filename, &ret)) != 0) { |
2265 | if (EC_GROUP_get_order(group, order, bnctx) != 1) | 347 | fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR); |
2266 | fatal("%s: EC_GROUP_get_order failed", __func__); | 348 | /* Old authfile.c ignored all file errors. */ |
2267 | if (EC_POINT_get_affine_coordinates_GFp(group, public, | 349 | if (r == SSH_ERR_SYSTEM_ERROR) |
2268 | x, y, bnctx) != 1) | 350 | debug("%s: %s", __func__, ssh_err(r)); |
2269 | fatal("%s: EC_POINT_get_affine_coordinates_GFp", __func__); | 351 | else |
2270 | if (BN_num_bits(x) <= BN_num_bits(order) / 2) { | 352 | error("%s: %s", __func__, ssh_err(r)); |
2271 | error("%s: public key x coordinate too small: " | 353 | return NULL; |
2272 | "bits(x) = %d, bits(order)/2 = %d", __func__, | ||
2273 | BN_num_bits(x), BN_num_bits(order) / 2); | ||
2274 | goto out; | ||
2275 | } | ||
2276 | if (BN_num_bits(y) <= BN_num_bits(order) / 2) { | ||
2277 | error("%s: public key y coordinate too small: " | ||
2278 | "bits(y) = %d, bits(order)/2 = %d", __func__, | ||
2279 | BN_num_bits(x), BN_num_bits(order) / 2); | ||
2280 | goto out; | ||
2281 | } | 354 | } |
355 | return ret; | ||
2282 | 356 | ||
2283 | /* nQ == infinity (n == order of subgroup) */ | 357 | } |
2284 | if ((nq = EC_POINT_new(group)) == NULL) | ||
2285 | fatal("%s: BN_CTX_tmp failed", __func__); | ||
2286 | if (EC_POINT_mul(group, nq, NULL, public, order, bnctx) != 1) | ||
2287 | fatal("%s: EC_GROUP_mul failed", __func__); | ||
2288 | if (EC_POINT_is_at_infinity(group, nq) != 1) { | ||
2289 | error("%s: received degenerate public key (nQ != infinity)", | ||
2290 | __func__); | ||
2291 | goto out; | ||
2292 | } | ||
2293 | 358 | ||
2294 | /* x < order - 1, y < order - 1 */ | 359 | Key * |
2295 | if (!BN_sub(tmp, order, BN_value_one())) | 360 | key_load_public(const char *filename, char **commentp) |
2296 | fatal("%s: BN_sub failed", __func__); | 361 | { |
2297 | if (BN_cmp(x, tmp) >= 0) { | 362 | int r; |
2298 | error("%s: public key x coordinate >= group order - 1", | 363 | Key *ret = NULL; |
2299 | __func__); | 364 | |
2300 | goto out; | 365 | if ((r = sshkey_load_public(filename, &ret, commentp)) != 0) { |
2301 | } | 366 | fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR); |
2302 | if (BN_cmp(y, tmp) >= 0) { | 367 | /* Old authfile.c ignored all file errors. */ |
2303 | error("%s: public key y coordinate >= group order - 1", | 368 | if (r == SSH_ERR_SYSTEM_ERROR) |
2304 | __func__); | 369 | debug("%s: %s", __func__, ssh_err(r)); |
2305 | goto out; | 370 | else |
371 | error("%s: %s", __func__, ssh_err(r)); | ||
372 | return NULL; | ||
2306 | } | 373 | } |
2307 | ret = 0; | ||
2308 | out: | ||
2309 | BN_CTX_free(bnctx); | ||
2310 | EC_POINT_free(nq); | ||
2311 | return ret; | 374 | return ret; |
2312 | } | 375 | } |
2313 | 376 | ||
2314 | int | 377 | Key * |
2315 | key_ec_validate_private(const EC_KEY *key) | 378 | key_load_private(const char *path, const char *passphrase, |
2316 | { | 379 | char **commentp) |
2317 | BN_CTX *bnctx; | 380 | { |
2318 | BIGNUM *order, *tmp; | 381 | int r; |
2319 | int ret = -1; | 382 | Key *ret = NULL; |
2320 | 383 | ||
2321 | if ((bnctx = BN_CTX_new()) == NULL) | 384 | if ((r = sshkey_load_private(path, passphrase, &ret, commentp)) != 0) { |
2322 | fatal("%s: BN_CTX_new failed", __func__); | 385 | fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR); |
2323 | BN_CTX_start(bnctx); | 386 | /* Old authfile.c ignored all file errors. */ |
2324 | 387 | if (r == SSH_ERR_SYSTEM_ERROR || | |
2325 | if ((order = BN_CTX_get(bnctx)) == NULL || | 388 | r == SSH_ERR_KEY_WRONG_PASSPHRASE) |
2326 | (tmp = BN_CTX_get(bnctx)) == NULL) | 389 | debug("%s: %s", __func__, ssh_err(r)); |
2327 | fatal("%s: BN_CTX_get failed", __func__); | 390 | else |
2328 | 391 | error("%s: %s", __func__, ssh_err(r)); | |
2329 | /* log2(private) > log2(order)/2 */ | 392 | return NULL; |
2330 | if (EC_GROUP_get_order(EC_KEY_get0_group(key), order, bnctx) != 1) | ||
2331 | fatal("%s: EC_GROUP_get_order failed", __func__); | ||
2332 | if (BN_num_bits(EC_KEY_get0_private_key(key)) <= | ||
2333 | BN_num_bits(order) / 2) { | ||
2334 | error("%s: private key too small: " | ||
2335 | "bits(y) = %d, bits(order)/2 = %d", __func__, | ||
2336 | BN_num_bits(EC_KEY_get0_private_key(key)), | ||
2337 | BN_num_bits(order) / 2); | ||
2338 | goto out; | ||
2339 | } | 393 | } |
394 | return ret; | ||
395 | } | ||
2340 | 396 | ||
2341 | /* private < order - 1 */ | 397 | Key * |
2342 | if (!BN_sub(tmp, order, BN_value_one())) | 398 | key_load_private_cert(int type, const char *filename, const char *passphrase, |
2343 | fatal("%s: BN_sub failed", __func__); | 399 | int *perm_ok) |
2344 | if (BN_cmp(EC_KEY_get0_private_key(key), tmp) >= 0) { | 400 | { |
2345 | error("%s: private key >= group order - 1", __func__); | 401 | int r; |
2346 | goto out; | 402 | Key *ret = NULL; |
403 | |||
404 | if ((r = sshkey_load_private_cert(type, filename, passphrase, | ||
405 | &ret, perm_ok)) != 0) { | ||
406 | fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR); | ||
407 | /* Old authfile.c ignored all file errors. */ | ||
408 | if (r == SSH_ERR_SYSTEM_ERROR || | ||
409 | r == SSH_ERR_KEY_WRONG_PASSPHRASE) | ||
410 | debug("%s: %s", __func__, ssh_err(r)); | ||
411 | else | ||
412 | error("%s: %s", __func__, ssh_err(r)); | ||
413 | return NULL; | ||
2347 | } | 414 | } |
2348 | ret = 0; | ||
2349 | out: | ||
2350 | BN_CTX_free(bnctx); | ||
2351 | return ret; | 415 | return ret; |
2352 | } | 416 | } |
2353 | 417 | ||
2354 | #if defined(DEBUG_KEXECDH) || defined(DEBUG_PK) | 418 | Key * |
2355 | void | 419 | key_load_private_type(int type, const char *filename, const char *passphrase, |
2356 | key_dump_ec_point(const EC_GROUP *group, const EC_POINT *point) | 420 | char **commentp, int *perm_ok) |
2357 | { | 421 | { |
2358 | BIGNUM *x, *y; | 422 | int r; |
2359 | BN_CTX *bnctx; | 423 | Key *ret = NULL; |
2360 | 424 | ||
2361 | if (point == NULL) { | 425 | if ((r = sshkey_load_private_type(type, filename, passphrase, |
2362 | fputs("point=(NULL)\n", stderr); | 426 | &ret, commentp, perm_ok)) != 0) { |
2363 | return; | 427 | fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR); |
428 | /* Old authfile.c ignored all file errors. */ | ||
429 | if (r == SSH_ERR_SYSTEM_ERROR || | ||
430 | (r == SSH_ERR_KEY_WRONG_PASSPHRASE)) | ||
431 | debug("%s: %s", __func__, ssh_err(r)); | ||
432 | else | ||
433 | error("%s: %s", __func__, ssh_err(r)); | ||
434 | return NULL; | ||
2364 | } | 435 | } |
2365 | if ((bnctx = BN_CTX_new()) == NULL) | 436 | return ret; |
2366 | fatal("%s: BN_CTX_new failed", __func__); | ||
2367 | BN_CTX_start(bnctx); | ||
2368 | if ((x = BN_CTX_get(bnctx)) == NULL || (y = BN_CTX_get(bnctx)) == NULL) | ||
2369 | fatal("%s: BN_CTX_get failed", __func__); | ||
2370 | if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) != | ||
2371 | NID_X9_62_prime_field) | ||
2372 | fatal("%s: group is not a prime field", __func__); | ||
2373 | if (EC_POINT_get_affine_coordinates_GFp(group, point, x, y, bnctx) != 1) | ||
2374 | fatal("%s: EC_POINT_get_affine_coordinates_GFp", __func__); | ||
2375 | fputs("x=", stderr); | ||
2376 | BN_print_fp(stderr, x); | ||
2377 | fputs("\ny=", stderr); | ||
2378 | BN_print_fp(stderr, y); | ||
2379 | fputs("\n", stderr); | ||
2380 | BN_CTX_free(bnctx); | ||
2381 | } | 437 | } |
2382 | 438 | ||
2383 | void | 439 | #ifdef WITH_OPENSSL |
2384 | key_dump_ec_key(const EC_KEY *key) | 440 | Key * |
2385 | { | 441 | key_load_private_pem(int fd, int type, const char *passphrase, |
2386 | const BIGNUM *exponent; | 442 | char **commentp) |
2387 | 443 | { | |
2388 | key_dump_ec_point(EC_KEY_get0_group(key), EC_KEY_get0_public_key(key)); | 444 | int r; |
2389 | fputs("exponent=", stderr); | 445 | Key *ret = NULL; |
2390 | if ((exponent = EC_KEY_get0_private_key(key)) == NULL) | 446 | |
2391 | fputs("(NULL)", stderr); | 447 | if ((r = sshkey_load_private_pem(fd, type, passphrase, |
2392 | else | 448 | &ret, commentp)) != 0) { |
2393 | BN_print_fp(stderr, EC_KEY_get0_private_key(key)); | 449 | fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR); |
2394 | fputs("\n", stderr); | 450 | if (r == SSH_ERR_KEY_WRONG_PASSPHRASE) |
451 | debug("%s: %s", __func__, ssh_err(r)); | ||
452 | else | ||
453 | error("%s: %s", __func__, ssh_err(r)); | ||
454 | return NULL; | ||
455 | } | ||
456 | return ret; | ||
2395 | } | 457 | } |
2396 | #endif /* defined(DEBUG_KEXECDH) || defined(DEBUG_PK) */ | 458 | #endif /* WITH_OPENSSL */ |
2397 | #endif /* OPENSSL_HAS_ECC */ | ||
2398 | 459 | ||
2399 | void | 460 | int |
2400 | key_private_serialize(const Key *key, Buffer *b) | 461 | key_perm_ok(int fd, const char *filename) |
2401 | { | 462 | { |
2402 | buffer_put_cstring(b, key_ssh_name(key)); | 463 | return sshkey_perm_ok(fd, filename) == 0 ? 1 : 0; |
2403 | switch (key->type) { | ||
2404 | case KEY_RSA: | ||
2405 | buffer_put_bignum2(b, key->rsa->n); | ||
2406 | buffer_put_bignum2(b, key->rsa->e); | ||
2407 | buffer_put_bignum2(b, key->rsa->d); | ||
2408 | buffer_put_bignum2(b, key->rsa->iqmp); | ||
2409 | buffer_put_bignum2(b, key->rsa->p); | ||
2410 | buffer_put_bignum2(b, key->rsa->q); | ||
2411 | break; | ||
2412 | case KEY_RSA_CERT_V00: | ||
2413 | case KEY_RSA_CERT: | ||
2414 | if (key->cert == NULL || buffer_len(&key->cert->certblob) == 0) | ||
2415 | fatal("%s: no cert/certblob", __func__); | ||
2416 | buffer_put_string(b, buffer_ptr(&key->cert->certblob), | ||
2417 | buffer_len(&key->cert->certblob)); | ||
2418 | buffer_put_bignum2(b, key->rsa->d); | ||
2419 | buffer_put_bignum2(b, key->rsa->iqmp); | ||
2420 | buffer_put_bignum2(b, key->rsa->p); | ||
2421 | buffer_put_bignum2(b, key->rsa->q); | ||
2422 | break; | ||
2423 | case KEY_DSA: | ||
2424 | buffer_put_bignum2(b, key->dsa->p); | ||
2425 | buffer_put_bignum2(b, key->dsa->q); | ||
2426 | buffer_put_bignum2(b, key->dsa->g); | ||
2427 | buffer_put_bignum2(b, key->dsa->pub_key); | ||
2428 | buffer_put_bignum2(b, key->dsa->priv_key); | ||
2429 | break; | ||
2430 | case KEY_DSA_CERT_V00: | ||
2431 | case KEY_DSA_CERT: | ||
2432 | if (key->cert == NULL || buffer_len(&key->cert->certblob) == 0) | ||
2433 | fatal("%s: no cert/certblob", __func__); | ||
2434 | buffer_put_string(b, buffer_ptr(&key->cert->certblob), | ||
2435 | buffer_len(&key->cert->certblob)); | ||
2436 | buffer_put_bignum2(b, key->dsa->priv_key); | ||
2437 | break; | ||
2438 | #ifdef OPENSSL_HAS_ECC | ||
2439 | case KEY_ECDSA: | ||
2440 | buffer_put_cstring(b, key_curve_nid_to_name(key->ecdsa_nid)); | ||
2441 | buffer_put_ecpoint(b, EC_KEY_get0_group(key->ecdsa), | ||
2442 | EC_KEY_get0_public_key(key->ecdsa)); | ||
2443 | buffer_put_bignum2(b, EC_KEY_get0_private_key(key->ecdsa)); | ||
2444 | break; | ||
2445 | case KEY_ECDSA_CERT: | ||
2446 | if (key->cert == NULL || buffer_len(&key->cert->certblob) == 0) | ||
2447 | fatal("%s: no cert/certblob", __func__); | ||
2448 | buffer_put_string(b, buffer_ptr(&key->cert->certblob), | ||
2449 | buffer_len(&key->cert->certblob)); | ||
2450 | buffer_put_bignum2(b, EC_KEY_get0_private_key(key->ecdsa)); | ||
2451 | break; | ||
2452 | #endif /* OPENSSL_HAS_ECC */ | ||
2453 | case KEY_ED25519: | ||
2454 | buffer_put_string(b, key->ed25519_pk, ED25519_PK_SZ); | ||
2455 | buffer_put_string(b, key->ed25519_sk, ED25519_SK_SZ); | ||
2456 | break; | ||
2457 | case KEY_ED25519_CERT: | ||
2458 | if (key->cert == NULL || buffer_len(&key->cert->certblob) == 0) | ||
2459 | fatal("%s: no cert/certblob", __func__); | ||
2460 | buffer_put_string(b, buffer_ptr(&key->cert->certblob), | ||
2461 | buffer_len(&key->cert->certblob)); | ||
2462 | buffer_put_string(b, key->ed25519_pk, ED25519_PK_SZ); | ||
2463 | buffer_put_string(b, key->ed25519_sk, ED25519_SK_SZ); | ||
2464 | break; | ||
2465 | } | ||
2466 | } | 464 | } |
2467 | 465 | ||
2468 | Key * | 466 | int |
2469 | key_private_deserialize(Buffer *blob) | 467 | key_in_file(Key *key, const char *filename, int strict_type) |
2470 | { | 468 | { |
2471 | char *type_name; | 469 | int r; |
2472 | Key *k = NULL; | 470 | |
2473 | u_char *cert; | 471 | if ((r = sshkey_in_file(key, filename, strict_type)) != 0) { |
2474 | u_int len, pklen, sklen; | 472 | fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR); |
2475 | int type; | 473 | if (r == SSH_ERR_SYSTEM_ERROR && errno == ENOENT) |
2476 | #ifdef OPENSSL_HAS_ECC | 474 | return 0; |
2477 | char *curve; | 475 | error("%s: %s", __func__, ssh_err(r)); |
2478 | BIGNUM *exponent; | 476 | return r == SSH_ERR_KEY_NOT_FOUND ? 0 : -1; |
2479 | EC_POINT *q; | ||
2480 | #endif | ||
2481 | |||
2482 | type_name = buffer_get_string(blob, NULL); | ||
2483 | type = key_type_from_name(type_name); | ||
2484 | switch (type) { | ||
2485 | case KEY_DSA: | ||
2486 | k = key_new_private(type); | ||
2487 | buffer_get_bignum2(blob, k->dsa->p); | ||
2488 | buffer_get_bignum2(blob, k->dsa->q); | ||
2489 | buffer_get_bignum2(blob, k->dsa->g); | ||
2490 | buffer_get_bignum2(blob, k->dsa->pub_key); | ||
2491 | buffer_get_bignum2(blob, k->dsa->priv_key); | ||
2492 | break; | ||
2493 | case KEY_DSA_CERT_V00: | ||
2494 | case KEY_DSA_CERT: | ||
2495 | cert = buffer_get_string(blob, &len); | ||
2496 | if ((k = key_from_blob(cert, len)) == NULL) | ||
2497 | fatal("Certificate parse failed"); | ||
2498 | free(cert); | ||
2499 | key_add_private(k); | ||
2500 | buffer_get_bignum2(blob, k->dsa->priv_key); | ||
2501 | break; | ||
2502 | #ifdef OPENSSL_HAS_ECC | ||
2503 | case KEY_ECDSA: | ||
2504 | k = key_new_private(type); | ||
2505 | k->ecdsa_nid = key_ecdsa_nid_from_name(type_name); | ||
2506 | curve = buffer_get_string(blob, NULL); | ||
2507 | if (k->ecdsa_nid != key_curve_name_to_nid(curve)) | ||
2508 | fatal("%s: curve names mismatch", __func__); | ||
2509 | free(curve); | ||
2510 | k->ecdsa = EC_KEY_new_by_curve_name(k->ecdsa_nid); | ||
2511 | if (k->ecdsa == NULL) | ||
2512 | fatal("%s: EC_KEY_new_by_curve_name failed", | ||
2513 | __func__); | ||
2514 | q = EC_POINT_new(EC_KEY_get0_group(k->ecdsa)); | ||
2515 | if (q == NULL) | ||
2516 | fatal("%s: BN_new failed", __func__); | ||
2517 | if ((exponent = BN_new()) == NULL) | ||
2518 | fatal("%s: BN_new failed", __func__); | ||
2519 | buffer_get_ecpoint(blob, | ||
2520 | EC_KEY_get0_group(k->ecdsa), q); | ||
2521 | buffer_get_bignum2(blob, exponent); | ||
2522 | if (EC_KEY_set_public_key(k->ecdsa, q) != 1) | ||
2523 | fatal("%s: EC_KEY_set_public_key failed", | ||
2524 | __func__); | ||
2525 | if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1) | ||
2526 | fatal("%s: EC_KEY_set_private_key failed", | ||
2527 | __func__); | ||
2528 | if (key_ec_validate_public(EC_KEY_get0_group(k->ecdsa), | ||
2529 | EC_KEY_get0_public_key(k->ecdsa)) != 0) | ||
2530 | fatal("%s: bad ECDSA public key", __func__); | ||
2531 | if (key_ec_validate_private(k->ecdsa) != 0) | ||
2532 | fatal("%s: bad ECDSA private key", __func__); | ||
2533 | BN_clear_free(exponent); | ||
2534 | EC_POINT_free(q); | ||
2535 | break; | ||
2536 | case KEY_ECDSA_CERT: | ||
2537 | cert = buffer_get_string(blob, &len); | ||
2538 | if ((k = key_from_blob(cert, len)) == NULL) | ||
2539 | fatal("Certificate parse failed"); | ||
2540 | free(cert); | ||
2541 | key_add_private(k); | ||
2542 | if ((exponent = BN_new()) == NULL) | ||
2543 | fatal("%s: BN_new failed", __func__); | ||
2544 | buffer_get_bignum2(blob, exponent); | ||
2545 | if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1) | ||
2546 | fatal("%s: EC_KEY_set_private_key failed", | ||
2547 | __func__); | ||
2548 | if (key_ec_validate_public(EC_KEY_get0_group(k->ecdsa), | ||
2549 | EC_KEY_get0_public_key(k->ecdsa)) != 0 || | ||
2550 | key_ec_validate_private(k->ecdsa) != 0) | ||
2551 | fatal("%s: bad ECDSA key", __func__); | ||
2552 | BN_clear_free(exponent); | ||
2553 | break; | ||
2554 | #endif | ||
2555 | case KEY_RSA: | ||
2556 | k = key_new_private(type); | ||
2557 | buffer_get_bignum2(blob, k->rsa->n); | ||
2558 | buffer_get_bignum2(blob, k->rsa->e); | ||
2559 | buffer_get_bignum2(blob, k->rsa->d); | ||
2560 | buffer_get_bignum2(blob, k->rsa->iqmp); | ||
2561 | buffer_get_bignum2(blob, k->rsa->p); | ||
2562 | buffer_get_bignum2(blob, k->rsa->q); | ||
2563 | |||
2564 | /* Generate additional parameters */ | ||
2565 | rsa_generate_additional_parameters(k->rsa); | ||
2566 | break; | ||
2567 | case KEY_RSA_CERT_V00: | ||
2568 | case KEY_RSA_CERT: | ||
2569 | cert = buffer_get_string(blob, &len); | ||
2570 | if ((k = key_from_blob(cert, len)) == NULL) | ||
2571 | fatal("Certificate parse failed"); | ||
2572 | free(cert); | ||
2573 | key_add_private(k); | ||
2574 | buffer_get_bignum2(blob, k->rsa->d); | ||
2575 | buffer_get_bignum2(blob, k->rsa->iqmp); | ||
2576 | buffer_get_bignum2(blob, k->rsa->p); | ||
2577 | buffer_get_bignum2(blob, k->rsa->q); | ||
2578 | break; | ||
2579 | case KEY_ED25519: | ||
2580 | k = key_new_private(type); | ||
2581 | k->ed25519_pk = buffer_get_string(blob, &pklen); | ||
2582 | k->ed25519_sk = buffer_get_string(blob, &sklen); | ||
2583 | if (pklen != ED25519_PK_SZ) | ||
2584 | fatal("%s: ed25519 pklen %d != %d", | ||
2585 | __func__, pklen, ED25519_PK_SZ); | ||
2586 | if (sklen != ED25519_SK_SZ) | ||
2587 | fatal("%s: ed25519 sklen %d != %d", | ||
2588 | __func__, sklen, ED25519_SK_SZ); | ||
2589 | break; | ||
2590 | case KEY_ED25519_CERT: | ||
2591 | cert = buffer_get_string(blob, &len); | ||
2592 | if ((k = key_from_blob(cert, len)) == NULL) | ||
2593 | fatal("Certificate parse failed"); | ||
2594 | free(cert); | ||
2595 | key_add_private(k); | ||
2596 | k->ed25519_pk = buffer_get_string(blob, &pklen); | ||
2597 | k->ed25519_sk = buffer_get_string(blob, &sklen); | ||
2598 | if (pklen != ED25519_PK_SZ) | ||
2599 | fatal("%s: ed25519 pklen %d != %d", | ||
2600 | __func__, pklen, ED25519_PK_SZ); | ||
2601 | if (sklen != ED25519_SK_SZ) | ||
2602 | fatal("%s: ed25519 sklen %d != %d", | ||
2603 | __func__, sklen, ED25519_SK_SZ); | ||
2604 | break; | ||
2605 | default: | ||
2606 | free(type_name); | ||
2607 | buffer_clear(blob); | ||
2608 | return NULL; | ||
2609 | } | ||
2610 | free(type_name); | ||
2611 | |||
2612 | /* enable blinding */ | ||
2613 | switch (k->type) { | ||
2614 | case KEY_RSA: | ||
2615 | case KEY_RSA_CERT_V00: | ||
2616 | case KEY_RSA_CERT: | ||
2617 | case KEY_RSA1: | ||
2618 | if (RSA_blinding_on(k->rsa, NULL) != 1) { | ||
2619 | error("%s: RSA_blinding_on failed", __func__); | ||
2620 | key_free(k); | ||
2621 | return NULL; | ||
2622 | } | ||
2623 | break; | ||
2624 | } | 477 | } |
2625 | return k; | 478 | return 1; |
2626 | } | 479 | } |