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